ARM32頁表-虛擬地址到實體地址的轉換
阿新 • • 發佈:2019-02-05
ARM32的頁表
頁表就是用於將虛擬地址轉換為實體地址的轉換關係表。訪問虛擬地址時,計算機通過頁表找到對應的實際實體地址訪問。
我們在上一節介紹了記憶體管理模組概圖,
怎麼完成從pgd 到 page的轉化呢?
linux 核心code是通過follow_page來完成的,原型如下:
static inline struct page *follow_page(struct vm_area_struct *vma,
unsigned long address, unsigned int foll_flags)
主要分成2步:
1. 由虛擬地址vaddr通過查詢頁表找到pte;
2. 由pte找出頁幀號pfn,然後在mem_map[]中找到相應的struct page結構。
這2步可以細化為如下幾步:
a. vma得到其所屬的mm;
b. mm->pgb(程序頁表pgb的起始位置)
c. mm->pgb 和 address 得到 address對應的pgd
#define PGDIR_SHIFT 21
/* to find an entry in a page-table-directory */
#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
d. pgd得到pte
在ARM頁表中,無pud和pmd,如下程式碼中的pmd就是步驟c中得到的pgd.
ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
#define pte_offset_map_lock(mm, pmd, address, ptlp) \
({ \
spinlock_t *__ptl = pte_lockptr(mm, pmd); \
pte_t *__pte = pte_offset_map(pmd, address); \
*(ptlp) = __ptl; \
spin_lock(__ptl); \
__pte; \
})
#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
e. pte得到pfn
unsigned long pfn = pte_pfn(pte);
#define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
f. pfn得到page
page = vm_normal_page(vma, address, pte);