Lab:Copy-on-Write Fork for xv6
1.实验目的
在xv6内核中实现copy-on-write-fork。
2.实验内容
xv6中的fork()系统调用将父进程的所有用户空间内存复制到子进程中。如果父对象很大,复制可能需要很长时间。此外,副本通常会浪费内存;在许多情况下,父级或子级都不会修改页面,因此原则上它们可以共享相同的物理内存。如果子级调用exec(),则效率低下的情况尤其明显,因为exec()将丢弃复制的页面,可能不会使用大部分页面。另一方面,如果父项和子项都使用一个页,并且其中一个或两个都在写,则确实需要一个副本。
3.实验步骤(要细化如何实现的思路或流程图)
1)首先先进入cow分支。
2)根据提示,先修改vm.c中的uvmcopy()函数,这是为了将分配新页面给子进程的模式改为将父级的物理页映射到子级的模式,同时相应要在kalloc.c中添加两个函数用来添加PTE reference和释放PTE reference。
3)进一步,修改usertrap(),以识别页错误。当一个COW page出现页错误时,使用kalloc()分配一个新页面,将旧页面复制到新页面,并用PTE_W将新页面安装到PTE中,经过查询,得知页错误的代号是15。(代码里的注释更详细)
4)接下来,根据题意,“一个物理页面只在最后一个reference消失的时候才会被free”,同时提示提到通过修改kalloc.c达成此目的,故修改如下。
同时,对于kinit,kfree,kalloc函数都要作出修改,详情见代码。
5)最后,修改vm.c中的copyout(),在遇到COW页时使用与页面错误相同的方式来应对(详情见代码)。
6)在测试之前,由于我们修改了一些文件,并添加了一个PTE_COW = (1L << 8),所以还要对应修改defs.h和riscv.h,修改完成后,进行测试。
4.实验结论与心得体会
实验过程中遇到了很多问题,查阅了很多资料,并且其实实际上还有一些不知所以然的东西存在,但是经历了不断的搜索和学习,对于copy on write的机制了解了许多,读、写、调试代码的能力也有所提升。