慢慢欣赏arm64内核启动2 保存启动参数

根据上一章节,bootloader将控制权交给内核,内核从__HEAD段的开头执行。该段的起始位置是_head

代码分析

_head

/*
 * Kernel startup entry point.
 * ---------------------------
 *
 * The requirements are:
 *   MMU = off, D-cache = off, I-cache = on or off,
 *   x0 = physical address to the FDT blob.
 *
 * This code is mostly position independent so you call this at
 * __pa(PAGE_OFFSET).
 *
 * Note that the callee-saved registers are used for storing variables
 * that are useful before the MMU is enabled. The allocations are described
 * in the entry routines.
 */
	__HEAD
_head:
	/*
	 * DO NOT MODIFY. Image header expected by Linux boot-loaders.
	 */
	 

	/*
	 * The following callee saved general purpose registers are used on the
	 * primary lowlevel boot path:
	 *
	 *  Register   Scope                      Purpose
	 *  x21        primary_entry() .. start_kernel()        FDT pointer passed at boot in x0
	 *  x23        primary_entry() .. start_kernel()        physical misalignment/KASLR offset
	 *  x28        __create_page_tables()                   callee preserved temp register
	 *  x19/x20    __primary_switch()                       callee preserved temp registers
	 *  x24        __primary_switch() .. relocate_kernel()  current RELR displacement
	 */
	 b	primary_entry			// branch to kernel start, magic

通过如上代码我们可以看出,_head开始是一句跳转语句,跳入到函数 primary_entry开始执行。

而我们看_head的上下文注释,我们可以得知,此时MMU尚未开启,所以链接地址和物理地址不相等的情况下,该段代码注定是位置无关代码,另外,bootloader给x0赋值,其值为设备树的基地址。下面我们接着分析primary_entry

primary_entry

该函数的代码如下

SYM_CODE_START(primary_entry)
	bl	preserve_boot_args
	bl	el2_setup			// Drop to EL1, w0=cpu_boot_mode
	adrp	x23, __PHYS_OFFSET
	and	x23, x23, MIN_KIMG_ALIGN - 1	// KASLR offset, defaults to 0
	bl	set_cpu_boot_mode_flag
	bl	__create_page_tables
	/*
	 * The following calls CPU setup code, see arch/arm64/mm/proc.S for
	 * details.
	 * On return, the CPU will be ready for the MMU to be turned on and
	 * the TCR will have been set.
	 */
	bl	__cpu_setup			// initialise processor
	b	__primary_switch
SYM_CODE_END(primary_entry)

我们可以看出,该函数短小精函,但是调用的函数可不少。我们只能一个函数一个函数分析

首先是preserve_boot_args

preserve_boot_args

/*
 * Preserve the arguments passed by the bootloader in x0 .. x3
 */
SYM_CODE_START_LOCAL(preserve_boot_args)
	mov	x21, x0				// x21=FDT

	adr_l	x0, boot_args			// record the contents of
	stp	x21, x1, [x0]			// x0 .. x3 at kernel entry
	stp	x2, x3, [x0, #16]

	dmb	sy				// needed before dc ivac with
						// MMU off

	mov	x1, #0x20			// 4 x 8 bytes
	b	__inval_dcache_area		// tail call
SYM_CODE_END(preserve_boot_args)

该函数的注释很清楚,保存bootloader传递下来的参数x0~x3

第一句表示先将x0,也就是设备树的基地址存放在x21

第二句表示将boot_args的物理地址加载到x0,为什么用adr_l这种加载物理地址的指令,就如之前说过的,这段代码是位置无关代码,不能用ldr命令,只能用adr命令

那么boot_args是什么东东呢

arch/arm64/kernel/setup.c:83:u64 __cacheline_aligned boot_args[4];

boot_args是个数组,里面有4个元素,正好对应preserve_boot_args注释的x0~x3

第三句和第四句分别是x0.x1,x2,x3的值存放到数组boot_args里面

然后在x1里面存放32,表示32个B,表示数组的长度,没毛病

参考

参考1

ARM64启动过程分析
https://blog.csdn.net/maybeYoc/article/details/111871673

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值