Speed up system calls
思路
题目要求在每个进程初始化时为它的页表插入一个页表项,内核通过这样预先缓存页表项的操作,来加速特定系统调用的执行速度。
由于前不久刚过完一遍《OSTEP》,因此我认为自己对页表机制还算比较熟悉,应对本 Lab 理应比较轻松,但在真正上手的时候,还是觉得有些无所适从,无奈老老实实地把 xv6 手册的第 3 章对照着代码仔细研读了一番,从中提炼出了几个关键的函数:
kernel/kalloc.c:kalloc
void *kalloc(void);
遍历空闲链表,寻找一个可分配的物理页面。若找到,返回该页面的首(物理)地址;否则,返回 0 (空指针)。
kernel/kalloc.c:kfree
void kfree(void *pa);
释放已分配的首地址为 pa
的物理页面,并更新空闲链表。
kernel/proc.c:allocproc
static struct proc *allocproc(void);
遍历进程数组 proc
,寻找未被使用的 struct proc
。若找到,则初始化其状态,为创建一个新的页表,并返回指向它的指针;否则,返回 0(空指针)。
kernel/proc.c:freeproc
static void freeproc(struct proc *p);
释放与进程 p
相关的数据的内存空间,并清空 p
的 struct proc
的所有信息。
kernel/vm.c:mappages
int mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm);
在页表 pagetrable
中创建从起始虚拟地址 va
到起始物理地址 pa
的页表项映射,页表项的 flags
位的访问权限部分设置为 perm
,其中大小为 size
,将 size
分为若干页,为这些页面创建 va + i * PGSIZE -> pa + i * PGSIZE
(i
代表页面的编号)的映射。
kernel/vm.c:uvmunmap
void uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages