课后作业 延迟页分配
为了提高物理内存的利用效率,在进程真正需要使用物理内存时,在执行分配.
一. 删除sbrk中的分配
- 我们需要修改
sys_sbrk()
中删除实际分配物理内存的代码,即growproc()
中的allocuvm()
部分. - 同时,我们需要增加进程当前可用的虚拟内存地址,即
myproc()->sz
.
修改后
修改完成后,在命令行执行echo hi
,将会看到类似如下的信息:
pid 3 sh: trap 14 err 6 on cpu 0 eip 0x111c addr 0xc004--kill proc
- 整条信息是由
trap.c
中的trap()
函数所打印. trap()
捕获的中断号为14, 即T_PGFLT
.因为没有对应了处理逻辑,因此调用了默认处理.- 因为MMU在Page Table中没有找到虚拟地址
0xc004
所对应的PTE,也意味着没有找到对应的物理页.因此产生异常中断.
二. 延迟分配
当我们了解了第一部分的原理后,第二部分也就是顺利成章了.我们需要在trap()
中添加T_PGFLT
的处理逻辑,为缺页的虚拟内存增加物理内存映射,然后返回用户进程.
提示:
- 查看
trap()/cprintf()
中是如何定位引起page fault
的虚拟地址. - 注意移植
allocuvm()
的代码,来实现我们的修改. - 注意使用
PGROUNDDOWN(va)
,来对齐缺页的下边界. - 增加
break
或者return
,来避免用户进程被杀. - 映射物理内存需要使用
mappages()
.要注意声明及去掉static. tf->trapno
等于T_PGFLT
,即为缺页引起的中断.
挑战
- 处理
sbrk()
参数为负. - 处理
sbrk()
参数过大. - ...