慢慢欣赏arm64内核启动3 primary_entry之el2_setup注释部分

分析

开始调用

primary_entry执行完保存参数的函数后,进入el2_setup函数

bl	el2_setup			// Drop to EL1, w0=cpu_boot_mode

查看调用函数的注释,含义是切换到EL1模式,出参为w0,保存进入内核时的异常等级。
看到这个注释,我联想起异常返回章节的通过sppr_elX和elr_elX切换异常等级的方法,我们分析代码看看是否这样实现的。
该函数较长,我们分段进行欣赏

分析注释

我们先看该函数的注释

	.section ".idmap.text","awx"

/*
 * If we're fortunate enough to boot at EL2, ensure that the world is
 * sane before dropping to EL1.
 *
 * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in w0 if
 * booted in EL1 or EL2 respectively.
 */

这表明,el2_setup在一个新的段里面,该段我们可以从vmlinux.lds看出端倪。

查看.idmap.text在内核镜像的位置

 .text : {
  _stext = .;
   . = ALIGN(8); __irqentry_text_start = .; *(.irqentry.text) __irqentry_text_end = .;
   . = ALIGN(8); __softirqentry_text_start = .; *(.softirqentry.text) __softirqentry_text_end = .;
   . = ALIGN(8); __entry_text_start = .; *(.entry.text) __entry_text_end = .;
   . = ALIGN(8); *(.text.hot .text.hot.*) *(.text .text.fixup) *(.text.unlikely .text.unlikely.*) *(.text.unknown .text.unknown.*) . = ALIGN(8); __noinstr_text_start = .; *(.noinstr.text) __noinstr_text_end = .; *(.text..refcount) *(.ref.text) *(.text.asan.* .text.tsan.*)
   . = ALIGN(8); __sched_text_start = .; *(.sched.text) __sched_text_end = .;
   . = ALIGN(8); __cpuidle_text_start = .; *(.cpuidle.text) __cpuidle_text_end = .;
   . = ALIGN(8); __lock_text_start = .; *(.spinlock.text) __lock_text_end = .;
   . = ALIGN(8); __kprobes_text_start = .; *(.kprobes.text) __kprobes_text_end = .;
   . = ALIGN(0x00001000); __hyp_idmap_text_start = .; *(.hyp.idmap.text) __hyp_idmap_text_end = .; __hyp_text_start = .; *(.hyp.text) . = ALIGN(0x00000008); __start___kvm_ex_table = .; *(__kvm_ex_table) __stop___kvm_ex_table = .; __hyp_text_end = .;
   . = ALIGN(0x00001000); __idmap_text_start = .; *(.idmap.text) __idmap_text_end = .;
   . = ALIGN(0x00001000); __hibernate_exit_text_start = .; *(.hibernate_exit.text) __hibernate_exit_text_end = .;
   . = ALIGN((1 << 12)); __entry_tramp_text_start = .; *(.entry.tramp.text) . = ALIGN((1 << 12)); __entry_tramp_text_end = .;
   *(.fixup)
   *(.gnu.warning)
  . = ALIGN(16);
  *(.got)
 }

 这说明,.idmap.text是.text的子段,至于为什么将el2_setup放到.text里面我也不清楚,但是我搜寻内核代码发现该函数多次被调用,所以猜测可能是该函数在后续阶段,也就是说MMU创建后也需要使用吧。比如

 	.pushsection ".idmap.text", "awx"
SYM_CODE_START(cpu_resume)
	bl	el2_setup		// if in EL2 drop to EL1 cleanly
	bl	__cpu_setup
	/* enable the MMU early - so we can access sleep_save_stash by va */
	adrp	x1, swapper_pg_dir
	bl	__enable_mmu
	ldr	x8, =_cpu_resume
	br	x8
SYM_CODE_END(cpu_resume)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值