臨時頁表分析
MMU開啟前,需要建立好kernel、dtb、trampoline等頁表。以便MMU開啟后,并且在內(nèi)存管理模塊運行之前,kernel可以正常初始化,dtb可以正常地被解析。這部分頁表都是臨時頁表,最終的頁表在setup_vm_final()建立。
臨時頁表創(chuàng)建順序:
首先為fixmap創(chuàng)建早期的PGD、PMD,這時PGD使用early_pg_dir
。然后對從kernel開始的前2M內(nèi)存建立二級頁表,此時PGD使用trampoline_pg_dir
,為這2M建立的頁表也叫作superpage
。再然后,對整個kernel創(chuàng)建二級頁表,此時PGD使用early_pg_dir
。最后為dtb預(yù)留4M大小創(chuàng)建二級頁表。
頁表創(chuàng)建函數(shù)
create_pgd_mapping()
void __init create_pgd_mapping(pgd_t *pgdp,
uintptr_t va, phys_addr_t pa,
phys_addr_t sz, pgprot_t prot)
pgdp
:PGD頁表
va
:虛擬地址
pa
:物理地址
sz
:映射大小,PGDIR_SIZE或PMD_SIZE或PTE_SIZE
prot
:PAGE_KERNEL_EXEC/PAGE_KERNEL表示當前是最后一級頁表,否則pa代表下一級頁表的物理地址
create_pmd_mapping()
static void __init create_pmd_mapping(pmd_t *pmdp,
uintptr_t va, phys_addr_t pa,
phys_addr_t sz, pgprot_t prot)
pmdp
:PMD頁表
va
:虛擬地址
pa
:物理地址
sz
:映射大小,PMD_SIZE或PAGE_SIZE
prot
:權(quán)限,PAGE_KERNEL_EXEC/PAGE_KERNEL表示當前是最后一級頁表,否則pa代表下一級頁表的物理地址
create_pte_mapping()
static void __init create_pte_mapping(pte_t *ptep,
uintptr_t va, phys_addr_t pa,
phys_addr_t sz, pgprot_t prot)
ptep
:PTE頁表
va
:虛擬地址
pa
:物理地址
sz
:映射大小,PAGE_SIZE
prot
:權(quán)限,PAGE_KERNEL_EXEC/PAGE_KERNEL表示當前是最后一級頁表,否則pa代表下一級頁表的物理地址
使用舉例
例如,將虛擬地址PAGE_OFFSET映射到物理地址pa,映射大小為4K,創(chuàng)建三級頁表PGD、PMD和PTE:
create_pgd_mapping(early_pg_dir,PAGE_OFFSET,
(uintptr_t)early_pmd,PGDIR_SIZE,PAGE_TABLE);
create_pmd_mapping(early_pmd,PAGE_OFFSET,
(uintptr_t)early_pte,PGDIR_SIZE,PAGE_TABLE);
create_pte_mapping(early_pte,PAGE_OFFSET,
(uintptr_t)pa,PAGE_SIZE,PAGE_KERNEL_EXEC);
這樣創(chuàng)建后,MMU就會根據(jù)PAGE_OFFSET在PGD中找到PMD,然后再PMD中找到PTE,最后取出物理地址。
-
Linux
+關(guān)注
關(guān)注
87文章
11208瀏覽量
208721 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4277瀏覽量
62325 -
RISC
+關(guān)注
關(guān)注
6文章
461瀏覽量
83637
發(fā)布評論請先 登錄
相關(guān)推薦
評論