- 论坛徽章:
- 0
|
原帖由 vestige 于 2008-3-29 12:42 发表 ![]()
我对这里还有一点疑问:
从软件的角度上来讲,因为它的项只有一个,32位,刚好可以存放与PGD中长度一样的地址指针。那么所谓先到PUD,到到PMD中做映射转换,就变成了保持原值不变,一一转手就可以了。这样,就 ...
不是,对页表的操作,是逐级获得指向下一级的指针,对于PUD的操作,实际上仍然是返回指向PGD的指针。
这里有段代码,虽然不是x86页表操作的代码,但性质是一样的,可以解释这个问题。
/*
代码中所有和pud有关的部分都是假的,被实现成空函数,例如pud_alloc_one()、pgd_cmpxchg_rel()等等
*/
pgd = pgd_offset(mm, mpaddr);
again_pgd:
if (unlikely(pgd_none(*pgd))) { // acquire semantics
pud_t *old_pud = NULL;
pud = pud_alloc_one(mm, mpaddr);
if (unlikely(!pgd_cmpxchg_rel(mm, pgd, old_pud, pud))) {
pud_free(pud);
goto again_pgd;
}
}
pud = pud_offset(pgd, mpaddr); //这里仍然返回指向PGD的指针
again_pud:
if (unlikely(pud_none(*pud))) { // acquire semantics
pmd_t* old_pmd = NULL;
pmd = pmd_alloc_one(mm, mpaddr);
if (unlikely(!pud_cmpxchg_rel(mm, pud, old_pmd, pmd))) {
pmd_free(pmd);
goto again_pud;
}
}
pmd = pmd_offset(pud, mpaddr);
again_pmd:
if (unlikely(pmd_none(*pmd))) { // acquire semantics
pte_t* old_pte = NULL;
pte_t* pte = pte_alloc_one_kernel(mm, mpaddr);
if (unlikely(!pmd_cmpxchg_kernel_rel(mm, pmd, old_pte, pte))) {
pte_free_kernel(pte);
goto again_pmd;
}
}
|
|
|