慢慢欣赏arm64内核启动14 primary_entry之__create_page_tables代码第四部分map_memory

分析代码

/*
 * 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
 *	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
 *
 * 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
	mov \sv, \rtbl
	mov \count, #0
	compute_indices \vstart, \vend, #PGDIR_SHIFT, \pgds, \istart, \iend, \count
	populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
	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
	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
	bic \count, \phys, #SWAPPER_BLOCK_SIZE - 1
	populate_entries \tbl, \count, \istart, \iend, \flags, #SWAPPER_BLOCK_SIZE, \tmp
	.endm

注释

第1行到第17行是注释,详细介绍每个参数的含义

第一个参数

第一个参数 tbl 即 table localtion 的缩写,根据链接地址的定义,我们认为所有的恒等映射的页表地址是连续的。即全局目录(PGD)后面是页上级目录(PUD),后面接着是页中间目录(PMD),最后是页表项(PTE)
所以不必费心传递不同级别页表的地址
入参对应的形参是 x0,在前面的代码中通过如下语句赋值

adrp	x0, idmap_pg_dir

第二个参数

第二个参数 rtbl 是下一级页表的起始地址,根据刚才的描述,下一级页表的起始地址其实是不用传达的,注释也做了说明,由于全局目录只占有1个页面,所以在函数的内部是通过 tbl + PAGE_SIZE 传递的
所以第二个参数本质是一个出参,在这里只是占用一个寄存器 x1而已

第三个参数

第三个参数是 vstart 表示虚拟地址的起始地址,从上一章节调用者的角度看,当映射是恒等映射时,虚拟地址等于物理地址
入参对应 x3,在前面的代码中通过如下语句赋值

adrp	x3, __idmap_text_start		// __pa(__idmap_text_start)

第四个参数

第四个参数是 vend 表示虚拟地址的结束地址,从上一章节调用者的角度看,当映射是恒等映射时,虚拟地址等于物理地址
入参对应 x6,在前面的代码中通过如下语句赋值

adr_l	x6, __idmap_text_end		// __pa(__idmap_text_end)

第五个参数

第五个参数是 flags,表示页表的属性,入参对应 x7,在前面的代码中通过如下语句赋值

mov	x7, SWAPPER_MM_MMUFLAGS

第六个参数

第六个参数 phys,表示物理地址,从上一章节调用者的角度看,当映射是恒等映射时,虚拟地址等于物理地址
入参也对应 x3

第七个参数

第七个参数 pgds 表示该页表的页表项数目,也就是全局目录的页表项数目,上一章节俄罗斯套娃里面讲过,入参对应 x4,其值为 512

第八个参数

第八个参数 istart,注释里没有说明,根据意思以及上下文代码的实现,应该是 index of start 的缩写,就是下一级页表的起始地址在该级页表的索引值,其范围为 [0, 512),
该参数为出参,对应 x10,需要在函数内部通过计算得到

第九个参数

第九个参数 iend,注释里没有说明,根据意思以及上下文代码的实现,应该是 index of end 的缩写,就是下一级页表的终止地址在该级页表的索引值,由于可能存在多个页表的可能性,
其范围为 [0, 512) + 该级页表最多包含的页表项的数目(例如四级映射每一级的最多的页表项为512) * 下一级页表的个数
该参数为出参,对应 x11,需要在函数内部通过计算得到

第十个参数

第十个参数 tmp,也是出参,对应 x12,作为临时变量使用,后面会讲解

第十一个参数

第十一个参数 count,也是出参,对应 x13, 是该级页表包含的有效的页表项

第十二个参数

第十二个参数 sv,也是出参,对应 x14,也是 临时变量,用于存储计算出来的下一级页表的起始物理地址

函数第一部分梳理

第19行 vend 自减1,其作用我们后面可以看到,但是根据经验判断,地址自减1,一般就是区间从0开始排序,最后一个元素的编号是总大小减1

第20行 正如前面所说的,全局目录页表只有一个,如果页表连续,下一级页表的物理地址 rtbl 为 全局目录页表 的物理地址 + 一个页的大小

第21行 把计算出来的下一级的页表物理基地值存放在临时变量 sv 里面,猜想下面的操作会改变 rtbl

第22行 将count赋值为0,从这里看不清原因

第23行 根据函数的名称 compute_indices 判断初步含义是 计算全局目录的页表起始索引和结束索引,我们下一章节详细分析该函数的内容

第24行 根据函数的名称 populate_entries 判断是产生和填充页表项,也就是说 将上个函数计算出来的页表起始索引 istart 和结束索引 iend 填充到 tbl 里面,我们下下章节详细分析该函数的内容

第25行 将临时变量的值,也就是保存的下一级页表的物理地址赋值给 tbl,表示下一步的操作是填充下一级页表的有效索引

第26行 将 rtbl 赋值给 sv,由于经过24行 populate_entries 的操作,原来的rtbl的值很有可能修改,修改为 下下级页表的起始物理地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值