// p->lock must be held when using these: enumprocstatestate;// Process state void *chan; // If non-zero, sleeping on chan int killed; // If non-zero, have been killed int xstate; // Exit status to be returned to parent's wait int pid; // Process ID
// wait_lock must be held when using this: structproc *parent;// Parent process
// these are private to the process, so p->lock need not be held. uint64 kstack; // Virtual address of kernel stack uint64 sz; // Size of process memory (bytes) pagetable_t pagetable; // User page table structtrapframe *trapframe;// data page for trampoline.S structcontextcontext;// swtch() here to run process structfile *ofile[NOFILE];// Open files structinode *cwd;// Current directory char name[16]; // Process name (debugging) structusyscall *ucall;// 不陷入内核的系统调用 };
The A bit indicates the virtual page has been read, written, or fetched from since the last time the A bit was cleared.这个A标志位是riscv处理器自己设置的,并不需要我们在软件上进行实现。实验指导上也说明,这个系统调用会把A标志位给清除。什么时候会把这个标志位置1呢,就是解决TLB缓存一次miss的情况下,会把页面的A置位1,也就是表示访问过。
intsys_pgaccess(void){ // lab pgtbl: your code here. // 获取参数 argaddr() and argint(). uint64 va; int sz; uint64 mask_addr; if (argaddr(0, &va) < 0){ return-1; } if (argint(1, &sz) < 0){ return-1; } if (argaddr(2, &mask_addr) < 0){ return-1; }
if (sz > 32 || sz < 0){ return-1; }
structproc *p = myproc();
int mask = 0; // 把这个掩码写入进程 p 用户态的地址 mask_addr 中去。 if (va > MAXVA){ return-1; } // va = PGROUNDDOWN(va); for (int i = 0; i < sz; i++){ // 找到相应的 pte 条目。 walk() in kernel/vm.c is very useful for finding the right PTEs. uint vaddr = va + i * PGSIZE; pte_t *pte = walk(p->pagetable, vaddr, 0); if (vaddr >= MAXVA){ return-1; }