我試圖爲arm平臺(僅針對內核頁表)模擬函數lookup_address(http://lxr.free-electrons.com/source/arch/x86/mm/pageattr.c#L373)。在ARM上跳轉頁表
重點是我從TTBR1獲取swapper_pg_dir的地址,到目前爲止這工作。 我用gdb檢查了它:
(gdb) file vmlinux
Reading symbols from vmlinux...done.
(gdb) p init_mm.pgd
$1 = (pgd_t *) 0xc0004000
(gdb)
,並從我的模塊代碼:
static pgd_t *get_global_pgd (void)
{
pgd_t *pgd;
unsigned int ttb_reg;
asm volatile (
" mrc p15, 0, %0, c2, c0, 1"
: "=r" (ttb_reg));
ttb_reg &= TTBR_MASK;
pgd = __va (ttb_reg);
pr_info ("get_global_pgd: %p\n", pgd);
return pgd;
}
和輸出:
bananapi kernel: [ 5665.358139] mod: get_global_pgd: c0004000
到目前爲止,這是匹配。 現在我計算正確的PGD的地址,這樣做的:
pgd = get_global_pgd() + pgd_index (addr);
而且,由於(地址>> 21)是0x600,我得到0xc0007000。 然後我繼續:
pud = pud_offset (pgd, addr);
pr_info ("pud: 0x%0x - %p\n",pud_val (*pud), pud);
pmd = pmd_offset (pud, addr);
pr_info ("pmd: 0x%0x - %p\n", pmd_val (*pmd), pmd);
if (pmd == NULL || pmd_none (*pmd)) {
return NULL;
}
return pte_offset_kernel (pmd, addr);
輸出:
bananapi kernel: [ 5665.390391] mod: pud: 0x4001140e - c0007000
bananapi kernel: [ 5665.401603] mod: pmd: 0x4001140e - c0007000
bananapi kernel: [ 5665.423838] mod: pte: 0xe59f119c - c0011020
的問題是,我得到的PTE似乎並沒有被罰款,因爲該PTE的屬性不匹配。 讓我們的地址從/ proc/kallsyms:
c0008054 t __create_page_tables
我可以使用gdb閱讀:
(gdb) x/2x 0xc0008054
0xc0008054 <__create_page_tables>: 0xe2884901 0xe1a00004
(gdb)
但是我從這個地址獲得PTE,不具有本旗:
我與檢查它(PTE是一個我從我的lookup_address了):
ret = pte_present (*pte);
pr_info ("pte_present: %d\n", ret);
pte_present是0(它檢查L_PTE_PRESENT標誌定義的include/asm/pgtable-2level.h),但只要我可以在GDB中讀取它就不應該爲0。
我已經與其他一些測試的地址,例如:0xc0035618:
c0035618 T __put_task_struct
而對於這一個L_PTE_PRESENT大設置。
我很確定我錯過了什麼,或者我錯了。
提前致謝!
'L_ *'屬性是Linux特有的,不一定是硬件。這裏已經有很多關於ARM Linux [爲這些維護第二組影子頁表的問題]的問題(http://lxr.free-electrons.com/source/arch/arm/include/asm/pgtable-2level)。 H)。 – Notlikethat
是的,我知道。實際上我認爲ARM不提供這些位,所以linux必須通過添加這些位來解決它。但是,當頁面錯誤被觸發時,Linux正在檢查這些位,所以我認爲它們是正確的。謝謝 – leberus
[ARM表的內核中的[頁表入口(PTE)描述符的可能的重複](http://stackoverflow.com/questions/16909101/page-table-entry-pte-descriptor-in-linux-kernel-for- arm) –