[英]Page Table Walk in Linux
Consider the following piece of code: 考虑以下代码:
pgd_t *pgd;
pte_t *ptep;
pud_t *pud;
pmd_t *pmd;
char *addr;
struct page *page = NULL;
struct mm_struct *mm = current->mm;
pgd = pgd_offset(mm, addr);
if (pgd_none(*pgd) || pgd_bad(*pgd))
goto out;
printk(KERN_NOTICE "Valid pgd");
pud = pud_offset(pgd, addr);
if (pud_none(*pud) || pud_bad(*pud))
goto out;
printk(KERN_NOTICE "Valid pud");
pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd) || pmd_bad(*pmd))
goto out;
printk(KERN_NOTICE "Valid pmd");
ptep = pte_offset_map(pmd, addr);
if (!ptep)
goto out;
addr = ptep->pte;
printk(KERN_INFO "byte = %d\n", *(char *)__va(addr));
pte_unmap(ptep);
If I understand correctly, addr
should be the physical address corresponding to the user-space virtual address. 如果我理解正确,则
addr
应该是与用户空间虚拟地址相对应的物理地址。 Then I should be able to dereference that using __va
. 然后,我应该可以使用
__va
取消引用它。 However, it doesn't work. 但是,它不起作用。 If I use
pte_page
and kmap
, though, it works exactly how it is supposed to. 但是,如果我使用
pte_page
和kmap
,它将按预期的方式工作。 Why does this happen? 为什么会这样? I'm on x86-64, so high memory shouldn't be a problem?
我在x86-64上,所以高内存应该不是问题吗? Is there something else
kmap
does? kmap
还有其他功能吗?
I fixed the problem thanks to TonyTannous. 感谢TonyTannous,我解决了这个问题。 The page table entry doesn't contain just the physical address, but also some other bits used for access rights and the like.
页表条目不仅包含物理地址,还包含用于访问权限等的其他一些位。 The physical address can be obtained by masking it with
PTE_PFN_MASK
: 可以通过使用
PTE_PFN_MASK
进行屏蔽来获取物理地址:
addr = ptep->pte & PTE_PFN_MASK
I can then dereference it with __va
. 然后,我可以使用
__va
取消引用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.