early_fixmap_init

本文来分析early_fixmap_init函数的代码
基于如下的配置,没有pud,因此可以提取到关键的代码如下
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_4K_PAGES=y
CONFIG_PGTABLE_LEVELS=3

void __init early_fixmap_init(void)
{
	pud_t *pud;
	pmd_t *pmd;
	unsigned long addr = FIXADDR_START;

	pud = fixmap_pud(addr);
	if (pud_none(*pud))
		__pud_populate(pud, __pa_symbol(bm_pmd), PMD_TYPE_TABLE);
	pmd = fixmap_pmd(addr);
	__pmd_populate(pmd, __pa_symbol(bm_pte), PMD_TYPE_TABLE);
}

这个函数简单说,就是要给虚拟地址FIXADDR_START建立映射,但是没有对应的物理地址,也就是说映射只做一部分,没有为pte赋值。
在具体某项目的Virtual kernel memory layout中,FIXADDR_START=0xffffffbefe7fb000

[    0.000000]     fixed   : 0xffffffbefe7fb000 - 0xffffffbefec00000   (  4116 KB)

将其分解获得各页表的index为:
0xffffffbefe7fb000
011111011
111110011
111111011
L0=0b011111011=0xFB=251
L1=0b111110011=0x1F3=499
L2=0b111111011=0x1FB=507
因此,这个函数的作用就是为三个页表建立联系,分别是swapper_pg_dir,bm_pmd和bm_pte,关系是:
swapper_pg_dir[251]=bm_pmd
bm_pmd[499]=bm_pte

// 这里静态申请了两个page,分别存储pmd页表和pte页表
static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss;
static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused;

通过ramdump来验证上面的分析
System.map中有定义,当然也可以直接从ramdump中获取到:
ffffff8009cfc000 b bm_pte
ffffff8009cfd000 b bm_pmd
ffffff800aa86000 A swapper_pg_dir
ffffff800aa86000+0xFB8=ffffff800aa867d8
在这里插入图片描述
在这里插入图片描述
如上证明了swapper_pg_dir[251]=bm_pmd
ffffff8009cfd000+0x1F3
8=ffffff8009cfdf98
在这里插入图片描述
在这里插入图片描述
如上证明了bm_pmd[499]=bm_pte

关于页表中最后的3,这个是页表的flag,具体可以查看MMU的文档。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值