Lab:xv6 lazy page allocation
1.实验目的
O/S可以在页表硬件上使用的许多巧妙的技巧之一是延迟分配用户空间堆内存。Xv6应用程序使用sbrk()系统调用向内核请求堆内存。在我们给您的内核中,sbrk()分配物理内存并将其映射到进程的虚拟地址空间。但是,有些程序使用sbrk()来请求大量内存,但从未使用大部分内存,例如实现大型稀疏数组。为了对这种情况进行优化,复杂的内核延迟地分配用户内存。也就是说,sbrk()不分配物理内存,只是记住分配了哪些地址。当进程第一次尝试使用任何给定的内存页时,CPU会生成一个页错误,内核通过分配物理内存、将其归零并映射它来处理该错误。在本实验中,我们要向xv6添加这个延迟分配特性。
2.实验内容
1)实现一个打印页表内容的函数。在kernel/vm.c中定义函数;它有以下原型:voidvmprint(pagetable_t)。此函数将便于调试,并使您熟悉RISC-V页表。在exec.c中插入对vmprint的调用,以打印第一个用户进程的页表。
2) 从sbrk(n)系统调用实现中删除页分配,sbrk(n)系统调用是sysproc.c中的函数sys_sbrk()。sbrk(n)系统调用会将进程的内存大小增加n个字节,然后返回新分配区域的开始(即旧大小)。新的sbrk(n)应该只将进程的大小(myproc()->sz)增加n,然后返回原来的大小。它不应该分配内存——所以应该删除对growproc()的调用(但仍然需要增加进程的大小!)。
3)修改trap.c中的代码,通过在出错地址映射新分配的物理内存页,然后返回到用户空间,让进程继续执行,从而从用户空间响应页面错误。我们应该在生成“usertrap():…”消息的printf调用之前添加代码。
3.实验步骤(要细化如何实现的思路或流程图)
3.1 Print page table
2)根据提示,仿照freewalk来写一个vmprint。
3)根据题意要求,在exec.c中插入vmprint,令其能在第一个进程执行时打印页表。
4)根据提示,在defs.h中做出相应修改。
5)启动qemu,结果如下,与指导书相同,成功。
3.2 Eliminate allocation from sbrk()
1)根据题意要求,让sbrk(n)系统调用时,增长n byte的内存空间。
2)然后进行测试。
3.3 Lazy allocation
1)首先根据要求先修改trap.c中的usertrap(),详细见代码。
2)根据提示,我们还需要对vm.c的uvmunmap()进行修改,否则会panic,同时注意到可能会出错,我们需要引入两个头文件,”proc.h”和”spinlock.h”。
3)处理后重新执行echo hi,成功。
4)根据提示,我们要想成功通过usertests还需要进行一下修改(详情见代码)。
5)启动qemu,测试如下,与指导书相同,成功。
4.实验结论与心得体会
经过本次实验,对于线性地址的理解更为深入了,对Unix的分页机制以及地址方面的知识了解到了更多,同时,通过读写代码,实践能力有所提升,并且和操作系统课程所学到的理论知识相做结合,获益匪浅。