简体   繁体   English

Linux中的页表遍历

[英]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_pagekmap ,它将按预期的方式工作。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM