代码:https://github.com/RedemptionC/xv6-riscv-6s081/tree/lazy
本实验要实现的是lazy allocation
很多时候,一个进程可能使用sbrk申请了大量的内存,但是其中的大部分并没有使用,造成了浪费
我们要做的是修改sbrk的实现,sbrk不分配物理内存,just remember which addresses are allocated
当进程第一次试图使用任何内存时,产生一个page fault,再让kernel分配内存,清零,映射
本实验涉及了第三章和第四章的内容,所以要看的还是挺多的
分析:因为我们没有实际分配内存(建立pte),所以用户程序访问对应地址时就会page fault,也就是一个来自用户空间的trap(异常)
根据第四章,page fault(trap)时,硬件会做这些事:
禁用中断(clear sie bit in sstatus)
把pc复制到sepc
保存当前mode到sstatus的spp bit
设置scause为trap的原因
设置模式为supervisor
把stvec的值设为pc(stvec保存trap handler的地址)
从pc执行(执行trap handler)
struct trapframe {
/* 0 */ uint64 kernel_satp; // kernel page table
/* 8 */ uint64 kernel_sp; // top of process's kernel stack
/* 16 */ uint64 kernel_trap; // usertrap()
/* 24 */ uint64 epc; // saved user program counter
/* 32 */ uint64 kernel_hartid; // saved kernel tp
所以,page fault时,从uservec开始执行(trampoline.s),据书中所说,在进入用户空间之前,内核sscratch指向每个进程的trapframe,trapframe有空间用来保存寄存器的值,然后把一