参考自:
http://yalongyang.com/2012/10/xv6-lazy-page-allocation/
http://www.bubuko.com/infodetail-1300595.html
xv6使用lazy page allocation。
当进程需要更多的内存的时候,调用malloc申请更多的堆内存,而系统调用sbrk()完成该工作。但是有的进程会一次申请大量的内存,但是又可能根本用不到,比如说sparse array。所以说复杂的内核涉及会将实际的allocation的工作推迟到实际用的时候,发生了page fault了,然后再进行实际的分配
Part One: Eliminate allocation from sbrk()
对系统调用sbrk的实际实现sys_sbrk进行修改,只将进程的内存空间大小增加n,而不进行实际的分配。代码修改如下,即将growproc函数注释掉。
sysproc.c
返回的地址是新分配的地址空间的开头,在此处就是原来地址空间的末尾。我们增加了sz,但却并未实际增加进程大小。
再次启动xv6,运行echo hi,得到如下错误提示:
原因是当程序试图操作该内存区域的时候,发现该内存区域不是当前进程所有的,因为在sys_sbrk中根本没分配。
Part Two: Lazy allocation
在trap.c中添加lazy allocation。我们的代码不需要完美到注意到每个细节,当前我们只需要能够执行echo等简单代码即可。在众多的提示下:
Hint: look at the cprintf arguments to see how to find the virtual address that caused the page fault.
Hint: steal code from allocuvm() in vm.c, which is what sbrk() calls (via growproc()).
Hint: use PGROUNDDOWN(va) to round the faulting virtual address down to a page boundary.
Hint: break or return in order to avoid the cprintf and the proc->killed = 1.
Hint: you'll need to call mappages(). In order to do this you'll need to delete the static in the declaration of mappages() in vm.c, and you'll need to declare mappages() in trap.c. Add this declaration to trap.c before any call to mappages().
Hint: you can check whether a fault is a page fault by checking if tf->trapno is equal to T_PGFLT in trap().
得到如下:
结果暂时还有错,程序会不停进入trap函数,还没解决。