实验内容
- 实现
pgaccess()
,这是一个报告哪些页面已经被访问的系统调用。 - 函数的参数:(内核态从陷阱帧
trapframe
中获取)
- 用户页面的起始虚拟地址
- 页数量
- 1个用于存储结果的用户态地址的
buffer
(存储了每页的mask)
已有内容
sys_pgaccess()
的系统调用已给出,只需补充函数内容即可
修改内容kernel/sysproc.c
中补充函数内容
int
sys_pgaccess(void)
{
uint64 start_va;
int num_pages;
uint64 user_bitmask;
argaddr(0,&start_va);
argint(1, &num_pages);
argaddr(2, &user_bitmask);
if( num_pages <= 0 || num_pages > 64 ){
return -1;
}
struct proc* p = myproc();
uint64 bitmask = 0;
pte_t* pte;
for( int i = 0; i < num_pages; i++){
uint64 va = start_va + i*PGSIZE;
pte = walk(p->pagetable, va, 0);
if( pte && (*pte & PTE_A )){
bitmask |= (1<<i);
*pte &= ~PTE_A;
}
}
if( copyout(p->pagetable, user_bitmask, (char*)&bitmask, sizeof(bitmask)) < 0 ){
return -1;
}
return 0;
}
#define PTE_A (1L << 6)
| 63-54 | 53-28 | 27-10 | 9-8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 保留 | PPN | 保留 | RSW | D | A | G | U | X | W | R | V |
- 硬件置位:
PTE_A
和 PTE_D
由 CPU 自动管理,反映真实访问行为。 - 软件置位:其他标志位(如
PTE_V/PTE_R
)需操作系统维护。