fc00952f758 t next_pud
ffffffc00952f75c t walk_pmds
ffffffc00952f764 t do_pmd
ffffffc00952f77c t next_pmd
ffffffc00952f78c t skip_pmd
ffffffc00952f79c t walk_ptes
ffffffc00952f7a4 t do_pte
ffffffc00952f7c8 t skip_pte
ffffffc00952f7d8 t __idmap_kpti_secondary
ffffffc00952f820 T __cpu_setup
ffffffc00952f974 T __idmap_text_end //
- 假设虚拟地址位宽为48(我们定义的是CONFIG_ARM64_VA_BITS_48);
- 虚拟地址位宽(48)保存到X5寄存器;
- 把立即数VA_BITS_MIN(48)保存到全局变量vabits_actual中;
- 将__idmap_text_end的物理地址放到x5寄存器中,计算__idmap_text_end地址第一个1前0的个数。并判断__idmap_text_end地址是否超过VA_BITS_MIN所能表达的地址范围。其中TCR_T0SZ(VA_BITS_MIN) 表示TTBR0页表所能映射的大小,因为稍后我们创建的页表会填充到TTBR0寄存器里面;
- 把PGD页表包含的页表项保存到x4寄存器中(2^9);
- 把__idmap_text_end的物理地址放到x6寄存器中;
- 调用map_memory宏来创建这段恒等映射的页表;
map_memory x0, x1, x3, x6, x7, x3, x4, x10, x11, x12, x13, x14
(1) x0 --- idmap_pg_dir
(2) x1 --- 无效值,会在map_memory中根据tbl的值重新计算
(3) x3 --- __idmap_text_start
(4) x6 --- __idmap_text_end
(5) x7 --- SWAPPER_MM_MMUFLAGS
(6) x3 --- __idmap_text_start
(7) x4 --- idmap_ptrs_per_pgd
2.4.5 map_memory宏的解析
map_memory宏一共12个参数,参数的解释在下面代码的批注中解释的非常清楚。重要参数说明如下:
- tbl : 页表起始地址(pgd)
- rtbl : 下级页表起始地址(typically tbl + PAGE_SIZE)
- vstart: 要映射虚拟地址的起始地址
- vend : 要映射虚拟地址的结束地址
- flags : 最后一级页表的属性
- phys : 要映射物理地址的起始地址
- flags : pgd entries个数
/*
* Map memory for specified virtual address range. Each level of page table needed supports
* multiple entries. If a level requires n entries the next page table level is assumed to be
* formed from n pages.
*
* tbl: location of page table 页表起始地址(pgd)
* rtbl: address to be used for first level page table entry (typically tbl + PAGE_SIZE)下级页表起始地址
* vstart: virtual address of start of range 要映射虚拟地址的起始地址
* vend: virtual address of end of range - we map [vstart, vend - 1]要映射虚拟地址的结束地址
* flags: flags to use to map last level entries 最后一级页表的属性
* phys: physical address corresponding to vstart - physical memory is contiguous 要映射物理地址的起始地址
* pgds: the number of pgd entries :pgd entries个数
*
* Temporaries: istart, iend, tmp, count, sv - these need to be different registers
* Preserves: vstart, flags
* Corrupts: tbl, rtbl, vend, istart, iend, tmp, count, sv
*/
.macro map_memory, tbl, rtbl, vstart, vend, flags, phys, pgds, istart, iend, tmp, count, sv
sub \vend, \vend, #1
add \rtbl, \tbl, #PAGE_SIZE ---(1)
mov \sv, \rtbl
mov \count, #0
compute_indices \vstart, \vend, #PGDIR_SHIFT, \pgds, \istart, \iend, \count ---(2)
populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp ---(3)
mov \tbl, \sv
mov \sv, \rtbl
#if SWAPPER_PGTABLE_LEVELS > 3 //我们这里不成立
compute_indices \vstart, \vend, #PUD_SHIFT, #PTRS_PER_PUD, \istart, \iend, \count
populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
mov \tbl, \sv
mov \sv, \rtbl
#endif
#if SWAPPER_PGTABLE_LEVELS > 2 ---(4)
compute_indices \vstart, \vend, #SWAPPER_TABLE_SHIFT, #PTRS_PER_PMD, \istart, \iend, \count
populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
mov \tbl, \sv
#endif
compute_indices \vstart, \vend, #SWAPPER_BLOCK_SHIFT, #PTRS_PER_PTE, \istart, \iend, \count ---(5)
bic \count, \phys, #SWAPPER_BLOCK_SIZE - 1
populate_entries \tbl, \count, \istart, \iend, \flags, #SWAPPER_BLOCK_SIZE, \tmp
.endm
-
计算PUD基地址,rtbl是下级页表地址:PUD = PGD+PAGE_SIZE
-
compute_indices宏的功能:根据虚拟地址计算各级页表的索引值index
/*
* Compute indices of table entries from virt