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

分析代码

/*
 * Compute indices of table entries from virtual address range. If multiple entries
 * were needed in the previous page table level then the next page table level is assumed
 * to be composed of multiple pages. (This effectively scales the end index).
 *
 *	vstart:	virtual address of start of range
 *	vend:	virtual address of end of range - we map [vstart, vend]
 *	shift:	shift used to transform virtual address into index
 *	ptrs:	number of entries in page table
 *	istart:	index in table corresponding to vstart
 *	iend:	index in table corresponding to vend
 *	count:	On entry: how many extra entries were required in previous level, scales
 *			  our end index.
 *		On exit: returns how many extra entries required for next page table level
 *
 * Preserves:	vstart, vend, shift, ptrs
 * Returns:	istart, iend, count
 */
	.macro compute_indices, vstart, vend, shift, ptrs, istart, iend, count
	lsr	\iend, \vend, \shift
	mov	\istart, \ptrs
	sub	\istart, \istart, #1
	and	\iend, \iend, \istart	// iend = (vend >> shift) & (ptrs - 1)
	mov	\istart, \ptrs
	mul	\istart, \istart, \count
	add	\iend, \iend, \istart	// iend += (count - 1) * ptrs
					// our entries span multiple tables

	lsr	\istart, \vstart, \shift
	mov	\count, \ptrs
	sub	\count, \count, #1
	and	\istart, \istart, \count

	sub	\count, \iend, \istart
	.endm

注释

第1行到14行是注释,大概意思就是计算虚拟地址的有效索引。
需要注意的一点是,如果上一级页表需要很多有效条目,则下一级页表可能由多页组成。这句话什么意思呢,我们接着分析各个参数的含义。

第一个参数 vstart 入参,虚拟地址的起始地址

第二个参数 vend 入参,虚拟地址的结束地址,在上一章节中我们是将 vend 自减1的,恰好符合注释描述的区间概念,否则就多分配了一个页表项

第三个参数 shift 入参, 将虚拟地址转换为索引需要偏移的位数,调用者传过来的参数是 PGDIR_SHIFT,该参数我们在以前的章节中分析过,为39

第四个参数 ptrs 入参,表示该页表最多支持的索引数目,该参数我们在以前的章节中分析过,页全局目录最大支持 512

第五个参数 istart 出参,有效虚拟起始地址的的索引项

第六个参数 iend 出参,有效结束虚拟地址的索引项

第七个参数 count 即是入参,又是出参。
第一次调用的时候,入参传递0,
根据注释,出参统计有效页表项的数目,包括了跨多个页表的场景。
对于全局页表来说,最多就一个页,不会超过512,但是后面级别的页表就不好说了,只要全局页表的有效索引超过1,下一级的页表肯定是跨多个页表。

正式分析

下面我们正式分析这个宏

第20行 计算 将虚拟地址 vend 右移 shift 位,并存放在 iend 里面,处理掉 vend 的右半部分(对于 iend 来说);

第21行 第22行 将 ptrs 减1存放在 istart 里面,该数前面为多个bit0,后面全为bit1;

第23行 将 iend 与  istart 进行按位与的运算,计算出结果并存放在 iend 里面,这样处理掉了 vend 左半部分的无用位(对于 iend 来说);
对于 iend 来说,就剩下跨页的情况没有被处理了。不过不要着急,下面马上安排:)

第24行 再将 ptrs 存放在 istart 里面

第25行 将 count 与 ptrs 相乘,计算跨页的情况,跨页意味这增加 count 个页表项以及下一级 count 个页表
当计算 页全局目录时,如果该入参为0,可以认为全局目录的上一级页表为0;
当计算其余的目录时,如果该入参为2,表示需要增加2个页表项

第26行 表示补充了跨页的场景,iend 盖棺定论

第29行到第32行计算 istart,过程比 iend 简单,少了跨页的计算,别的都差不多

第34行 计算需要填充的索引数目,将结果赋值到 count;如果 iend 和 istart 相减为0, 表示这两个索引在一个页面,不存在跨页情况;
如果两着相减不为0,则表示两个索引不在一个页面,存在跨页情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值