sunus
unread,Nov 29, 2013, 2:50:07 AM11/29/13Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to xv6...@googlegroups.com, Chunis Deng
hi, all:
我现在lab2目测是完工了, 但是对pgdir_walk这个函数有些疑问:
先假设va对于的pdx为i
如果在*pde == NULL && create == True的情况的情况下, 我们会需要创建一个新的page.即 pde[i] = phyaddr-of-new-page. 但是, 新的pre[i]的权限我们该如何处理, 在我的代码中我是给予PTE_P, PTE_U, PTE_W权限. 但是我认为pgdir_walk应该只需要PTE_P就足够了吧?
还有一种情况就是, page_insert会插入新的page, 如果page_insert中插入的page的权限比pde[i]中多怎么办? 需要在page_insert中改写pde[i]的权限吗?
我的实现:
pte_t *
pgdir_walk(pde_t *pgdir, const void *va, int create)
{
pde_t *pde;
pte_t *pte;
pte_t *entry;
struct PageInfo *p;
pde = &pgdir[PDX(va)];
if ((!*pde) && create) {
p = page_alloc(ALLOC_ZERO);
if (!p)
return NULL;
p->pp_ref++;
*pde = page2pa(p);
*pde |= (PTE_P|PTE_U|PTE_W);
}
else if (!*pde)
return NULL;
entry = (pde_t *)PTE_ADDR(*pde);
pte = &entry[PTX(va)];
return (pte_t *)KADDR((pte_t)pte);
}
int
page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
{
struct PageInfo *page;
pte_t *pte;
pte = pgdir_walk(pgdir, va, 1);
if (!pte) {
// indicate that there is no free pages.
return -E_NO_MEM;
}
pp->pp_ref++;
if (*pte) {
page_remove(pgdir, va);
}
*pte = page2pa(pp);
*pte |= (PTE_P|perm);
tlb_invalidate(pgdir, va);
return 0;
}
我对权限的疑问主要来源于这个测试:
// check PDE permissions
for (i = 0; i < NPDENTRIES; i++) {
switch (i) {
case PDX(UVPT):
case PDX(KSTACKTOP-1):
case PDX(UPAGES):
assert(pgdir[i] & PTE_P);
break;
default:
if (i >= PDX(KERNBASE)) {
assert(pgdir[i] & PTE_P);
assert(pgdir[i] & PTE_W);
} else
assert(pgdir[i] == 0);
break;
}
}
如果pgdir_walk中没给予PTE_W权限的话, assert(pgdir[i] & PTE_W); 这个断言会失败, 但是我也不确定pgdir_walk是否是需要给予这些权限的地方 :(
多谢!
Sunus Lee
Best Wishes