簡體   English   中英

Linux中的頁表遍歷

[英]Page Table Walk in Linux

考慮以下代碼:

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);

如果我理解正確,則addr應該是與用戶空間虛擬地址相對應的物理地址。 然后,我應該可以使用__va取消引用它。 但是,它不起作用。 但是,如果我使用pte_pagekmap ,它將按預期的方式工作。 為什么會這樣? 我在x86-64上,所以高內存應該不是問題嗎? kmap還有其他功能嗎?

感謝TonyTannous,我解決了這個問題。 頁表條目不僅包含物理地址,還包含用於訪問權限等的其他一些位。 可以通過使用PTE_PFN_MASK進行屏蔽來獲取物理地址:

    addr = ptep->pte & PTE_PFN_MASK

然后,我可以使用__va取消引用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM