实验内容
- 实现
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
)需操作系统维护。