慢慢欣赏arm64内核启动9 primary_entry之el2_setup代码第七部分

基于aarch64分析kernel源码 三:启动代码分析 1、通过__HEAD将启动代码链接到文件开始位置。2、调用y ,进行初始化相关操作。3、调用调用函数。4、函数进入C语言环境初始化内核。 阅读详情

分析代码

	cbz	x2, install_el2_stub

	mov	w0, #BOOT_CPU_MODE_EL2		// This CPU booted in EL2
	isb
	ret

SYM_INNER_LABEL(install_el2_stub, SYM_L_LOCAL)
	/*
	 * When VHE is not in use, early init of EL2 and EL1 needs to be
	 * done here.
	 * When VHE _is_ in use, EL1 will not be used in the host and
	 * requires no configuration, and all non-hyp-specific EL2 setup
	 * will be done via the _EL1 system register aliases in __cpu_setup.
	 */
	mov_q	x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
	msr	sctlr_el1, x0

	/* Coprocessor traps. */
	mov	x0, #0x33ff
	msr	cptr_el2, x0			// Disable copro. traps to EL2

	/* SVE register access */
	mrs	x1, id_aa64pfr0_el1
	ubfx	x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4
	cbz	x1, 7f

	bic	x0, x0, #CPTR_EL2_TZ		// Also disable SVE traps
	msr	cptr_el2, x0			// Disable copro. traps to EL2
	isb
	mov	x1, #ZCR_ELx_LEN_MASK		// SVE: Enable full vector
	msr_s	SYS_ZCR_EL2, x1			// length for EL1.

	/* Hypervisor stub */
7:	adr_l	x0, __hyp_stub_vectors
	msr	vbar_el2, x0

	/* spsr */
	mov	x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
		      PSR_MODE_EL1h)
	msr	spsr_el2, x0
	msr	elr_el2, lr
	mov	w0, #BOOT_CPU_MODE_EL2		// This CPU booted in EL2
	eret
SYM_FUNC_END(el2_setup)

install_el2_stub

el2_setup分析了这么多,终于到了结尾部分。但是这段代码还是较长。我们一点点分析。
第1行代码:x2寄存器如果为0,则跳转到函数 install_el2_stub 执行;
其中,x2寄存器始终保存 VHE 的值,也就是说,如果当前 PE 不支持 VHE,则执行 install_el2_stub,我们分析一下 函数 install_el2_stub

第7行代码就是函数 install_el2_stub 的开头部分,这个函数看名字像是个桩函数,安装 el2 异常模式的桩,这是啥意思呢,我们先看一下注释吧。

第8行到14行是注释部分,我们尝试翻译一下:
如果 PE 不支持 VHE 模式,那么第一阶段的启动过程中,对异常模式 EL1/EL2 的初始化到此结束了;
但是如果 PE 支持 VHE 模式,那么主机侧不需要 EL1 异常模式,并且 EL1 异常模式也不需要配置,所有非hyp特有的EL2设置都将在函数__cpu_setup中通过EL1系统寄存器别名完成。
这段话表面翻译起来,还是绕,只能等到后续真正分析 __cpu_setup 再慢慢消化了。

第15行到16行代码在 el2_setup 的前面的章节分析过。

CPTR_EL2

第18行到第20行涉及到寄存器 CPTR_EL2, Architectural Feature Trap Register (EL2),该寄存器的含义如下:
Controls:
    Trapping to EL2 of access to CPACR, CPACR_EL1, trace functionality, and to SVE, Advanced SIMD and floating-point functionality.
    EL2 access to trace functionality, and to SVE, Advanced SIMD and floating-point functionality.
该寄存器用于控制对特定架构特性的陷阱(trap)行为。
具体来说,CPTR_EL2寄存器允许EL2(虚拟化扩展的虚拟监控程序Hypervisor运行的级别)管理对处理器某些功能的访问,当这些功能被访问时,可以决定是否将它们重定向为陷阱(trap)异常,以便EL2可以进行处理。
CPTR_EL2寄存器中的每一位都对应一个特定的架构特性或指令集扩展。当某位被设置为1时,表示对应的特性或指令集扩展的访问将被陷阱到EL2。这允许Hypervisor对底层硬件功能进行更细粒度的控制,防止客户操作系统(运行在EL1或更低级别)直接访问这些特性。
通过控制对特定架构特性的访问,CPTR_EL2有助于在虚拟化环境中实现安全隔离。它确保只有Hypervisor能够访问或控制那些可能对系统稳定性或安全性产生影响的特性。
根据具体的应用场景和安全需求,Hypervisor可以通过编程方式配置CPTR_EL2寄存器,灵活地启用或禁用对特定架构特性的陷阱。这种灵活性使得ARM64架构能够支持多种不同的虚拟化解决方案和场景。
魔数字0x33ff 主要涉及2个位域
TFP, bit [10]
Traps accesses to SVE, Advanced SIMD and floating-point functionality to EL2 when it is enabled in the current Security state, from both Execution states.
    0b'0 This control does not cause any instructions to be trapped.
    0b'1 Any attempt at EL0, EL1 or EL2, to execute an instruction that uses the registers associated with SVE, Advanced SIMD and floating-point execution is trapped to EL2 when it is enabled in the current Security state, subject to the exception prioritization rules, unless it is trapped by CPTR_EL2.TZ.
TZ, bit [8]
When SVE is implemented:
    Traps execution at EL2, EL1, or EL0 of SVE instructions and instructions that access SVE System registers to EL2 when it is enabled in the current Security state.
        0b'0 This control does not cause any instruction to be trapped.
        0b'1 This control causes these instructions to be trapped, subject to the exception prioritization rules.
        This field resets to an architecturally UNKNOWN value.
Otherwise:
    Reserved, RES1.

SVE

第22行到第25行涉及到 SVE寄存器的访问控制。
寄存器 ID_AA64PFR0_EL1 在前面的章节讲解过,宏 ID_AA64PFR0_SVE_SHIFT 的定义如下

#define ID_AA64PFR0_SVE_SHIFT		32

相关位域定义如下:
SVE, bits [35:32]
    From ARMv8.2:
        Scalable Vector Extension. Defined values are:
        0b'0000SVE is not implemented.
        0b'0001SVE is implemented.
        All other values are reserved.
    Otherwise:
        Reserved, RES0.
含义是:是否支持 SVE 矢量,如果不支持 SVE,则直接跳转到第34行。

第27行到第31行是对 SVE 的配置

异常向量入口

第33行到第35行异常向量入口地址的配置,当然,当前情况下,只是配置了个桩

第34行将 __hyp_stub_vectors 的地址加载到了x0寄存器;

第35行将 x0的值赋值给了寄存器 vbar_el2
VBAR_EL2, Vector Base Address Register (EL2)的含义如下:
Holds the vector base address for any exception that is taken to EL2.
也就是说,传递给EL2异常模式下的异常向量的入口地址。

异常模式EL2到EL1的切换

第37行到第43行是整个 el2_setup 的核心部分之一。主要作用就是当前 PE 如果不支持 VHE,那么需要从当前的EL2异常模式切换到EL1异常模式继续运行。

涉及到的宏定义如下:

#define PSR_F_BIT	0x00000040
#define PSR_I_BIT	0x00000080
#define PSR_A_BIT	0x00000100
#define PSR_D_BIT	0x00000200
#define PSR_MODE_EL1h	0x00000005


切换前需要设置两个寄存器:
    elr_el2:EL1从lr寄存器保留的地址继续运行的地址, lr保留的是 install_el2_stub 函数的返回地址;
    spsr_el2:EL2的状态保留在 spsr_el2寄存器(Saved Program Status Register (EL2))
        其中异常返回前(When exception taken from AArch64 state:),位域bits[3:0]的含义如下:
        M[3:0], bits [3:0]
        AArch64 state (Exception level and selected SP) that an exception was taken from.
        0b'0000    EL0t.
        0b'0100    EL1t.
        0b'0101    EL1h.
        Other values are reserved, and returning to an Exception level that is using AArch64 with a reserved
        value in this field is treated as an illegal exception return.
        The bits in this field are interpreted as follows:
            M[3:2] holds the Exception Level.
            M[1] is unused and is RES0 for all non-reserved values.
            M[0] is used to select the SP:
                0 means the SP is always SP0.
                1 means the exception SP is determined by the EL.
        This field resets to an architecturally UNKNOWN value.
        根据上面芯片手册的描述,我们得知,位域M[3:0]表示异常等级切换后,需要切换回的异常等级模式,根据宏定义 PSR_MODE_EL1h 的定义,我们得知切换到 EL1, 并且使用 SP1 作为堆栈
        其它涉及的位域bits[9:6]表示屏蔽所有的异常干扰

第42行将启动的异常模式EL2 保留在 w0中。

第43行 eret 进行模式切换,从EL2模式切换到EL1模式运行,切换到 install_el2_stub 函数的返回地址继续运行,注意,不是第3行,而是 el2_setup整个函数的lr寄存器,lr 保存的是进入 el2_setup 函数时下一条指令的地址,也就是 el2_setup 函数返回后应该继续执行的位置 继续运行。原因(nbz是jump指令而不是call指令),整个el2_setup就没有函数调用流程。

ARM64 Linux中断向量表与汇编处理全解析:从硬件响应到C语言入口 中断机制是计算机系统中处理异步事件的核心基础,它允许CPU在执行任务时,能够即时响应外部硬件请求。其工作原理是,当外设触发中断信号时,CPU会暂停当前执行流,保存现场状态,并根据预设的规则跳转到特定的处理程序。这一机制对于实现高并发、低延迟的系统至关重要,是驱动开发、操作系统调度和性能优化的技术基石。在ARM64架构的Linux内核中,这一过程始于异常向量表(Exception Vector Table),它作为硬件与软件约定的“应急地图”,由VBAR_ELx寄存器定位。当中断发生时,CPU会根据异常类型和 阅读详情

相关推荐

CTransformers: 高效的Python语言模型绑定库

CTransformers是一个为C/C++实现的Transformer模型提供Python绑定的开源库。它基于GGML库构建,旨在为开发者提供一种高效且易用的方式来在Python中使用各种流行的语言模型。支持多种流行的语言模型,如GPT-2、LLaMA、Falcon等提供统一的简单API接口支持GPU加速(CUDA和Metal)与Hugging Face Transformers和LangChain集成支持流式输出和嵌入计算。

helloaiworld的博客 1268

Linux内核源码 ---- el2_setup源码解析

kernel版本:5.10.129 进入内核的时候,arm64处理器的异常级别可能是1或者2,函数el2_setup的主要工作如下: 1、如果异常级别是1,那么在异常级别1执行内核 2、如果异常级别是2, 那么根据处理器是否支持虚拟化宿主扩展(Virtuallization Host Extensions,VHE),决定是否需要降级到异常级别1.具体实现代码如下: 该汇编函数,用w0寄存器保存返回值,返回值有两种:BOOT_CPU_MODE_EL1:表示当前CPU跳入内核时处于权限级EL1BOOT_CPU_

aigourensheng的博客 1500

医药行业新零售项目数据分析报告——基于Excel的分析与可视化

不同平台客户支付金额用数字+百分比展示更直观。各大区支付金额分析较为粗浅,后续可加入不同大区人数、配送费等进行细分分析。图表略微单一,可采用组合图,运用两个及以上维度对数据进行分析。数据来源本项目数据来源于某机构的项目案例,以上分析内容均为本人原创,不涉嫌抄袭。原做项目,新平台首发。

2401_84213513的博客 1495

ARMv8-A编程指导之ARMv8寄存器(3)

5 修改执行状态 在之前的章节我们描述了根据异常级别在AArch64和AArch32之间进行切换。现在我们从寄存器的视角考虑修改。 从AArch32的异常级别到AArch64的异常级别如下: (1)使用AArch32的任意低异常级别的高32位寄存器的值是UNKNOWN; (2)在AArch32过程中不能访问的寄存器仍保持在AArch32执行之前的状态; (3)EL3的异常条目,当EL2使用AArch32时,ELR_EL2的高32位的值是UNKNOWN; (4)与一...

flyingnosky的专栏 686

图像识别火灾检测系统实战:从火焰特征到YOLO部署全解析

计算机视觉技术正深入改变传统消防的感知方式。图像识别火灾检测利用摄像头采集的视频流,通过颜色、动态和形态特征分析,实现早期火情的自动发现与定位。其核心原理在于,火焰在视觉上具有独特的颜色分布、闪烁特性和轮廓变化,借助目标检测模型如YOLO,可在复杂场景中区分真实火焰与干扰物。这项技术广泛应用于仓库、园区、隧道等大空间场所,是智慧消防的重要支撑。本文从火焰视觉特征、数据集构建、模型选型与系统架构设计出发,结合部署实践中的误报与算力优化经验,为开发者提供一套可落地的视频火焰检测方案。

weixin_42533751的博客 245

究竟什么是虚拟同步机???虚拟同步机巨简单理解

同步发电机定子铁芯的内圆均匀分布着定子槽,槽内按一定规律嵌放着对称的三相绕组U1-U2、V1-V2、W1-W2,如图1所示。工作原理转子铁芯上装有制成一定形状的成对磁极,磁极上绕有励磁绕组。励磁绕组上通直流电时,会在电机的气隙中形成极性相间的分布磁场,称为励磁磁场。当原动机拖动转子以恒定速度旋转时,励磁磁场随转轴一起旋转并顺次切割定子各相绕组。定子电枢绕组中将会感应出大小和方向周期性变化的三相对称正弦感应电动势。各相电动势大小相等,相位各差120°。

weixin_53126442的博客 2608

[ARM异常]-ARMV8的异步异常(中断)详细介绍

1、VBAR寄存器的介绍 VBAR(Vector Base Address Register)的寄存器有: 如果是aarch64: VBAR_EL1 VBAR_EL2 VBAR_EL3 如果是aarch32 VBAR HVBAR MVBAR 在开启MMU的系统,VBAR中写入的是虚拟地址,以VBAR_EL1为例,介绍下field的使用: Bits [10:0] reserved Bits [11:63]: 如果不支持ARMv8.2-LVA(Large VA support:使用64kb页面时,

baron-周贺贺-代码改变世界ctw 6745

Flutter 中使用蓝牙插件报错,说没有权限怎么解决

2、在build.grale里面更改一下版本号,我修改的是targetSdkVersion这个版本号,需要根据你自己的版本进行更改,记得更改之后先flutter clean一下再run。搞了一晚上,没搞出来,第二天用同事手机测试发现他手机可以,我手机还是不行,才发现是Android版本问题,需要修改两处地方。废话不多说,咱先看报错信息。

zzj17637822814的博客 2289

arch/arm64/kernel/head.S文件——el2_setup函数分析

该汇编函数,用w0寄存器保存返回值,返回值有两种: BOOT_CPU_MODE_EL1:表示当前CPU跳入内核时处于权限级EL1 BOOT_CPU_MODE_EL2:表示当前CPU跳入内核时处于权限级EL2 ////////////////////////////////////// 1)在权限级ELx下,寄存器SPsel被设置为1时,堆栈寄存器SP就是用寄存器SP_ELx。 msr SPsel, #1 2)寄存器CurrentEL记录了当前CPU的权限级 ...

2328

24、汽车黑客技术全解析:诊断代码、车库创建与系统攻防

本文深入探讨了汽车黑客技术的核心内容,包括诊断代码模式与参数ID、创建开放车库社区、汽车系统相关技术、硬件与软件工具、攻击与防御手段,以及车辆通信与网络安全。无论你是汽车安全研究人员、爱好者还是开发者,都能从中获取全面的技术解析与实践指南。

Apple的专栏 228

【AI智能体】Claude Code +Superpowers 项目实战操作详解

Claude Code +Superpowers 项目实战操作详解

congge 4052

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

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

shipinsky的博客 348

自适应滤波-----LMS(Least Mean Square)算法

自适应滤波的意义所在 自适应滤波器解决非平稳的过程,因为实际信号的统计特性可能是非平稳的或者是未知的。 自适应滤波器的特点: 1.没有关于待提取信息的先验统计知识 2.直接利用观测数据依据某种判据在观测过程中不断递归更新 3.最优化 自适应滤波分类: 处理器的结构划分:横向结构、格型结构 重复一次计算自适应需要的数据划分:成批处理法、递归处理法 按调节算法...

heda3的博客 10万+

慢慢欣赏arm64内核启动8 primary_entry之el2_setup代码第六部分

【代码】慢慢欣赏arm64内核启动8 primary_entry之el2_setup代码第六部分。

shipinsky的博客 914

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

慢慢欣赏arm64内核启动7 primary_entry之el2_setup代码第五部分

【代码】慢慢欣赏arm64内核启动7 primary_entry之el2_setup代码第五部分。

shipinsky的博客 894

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

慢慢欣赏arm64内核启动20 primary_entry之__cpu_setup代码第二部分

【代码】慢慢欣赏arm64内核启动20 primary_entry之__cpu_setup代码第二部分。

shipinsky的博客 1030

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

慢慢欣赏arm64内核启动4 primary_entry之el2_setup代码第二部分

el2_setup继续执行就到了EL2异常等级的虚拟化部分的解析和处理部分。

shipinsky的博客 925

慢慢欣赏arm64内核启动6 primary_entry之el2_setup代码第四部分

【代码】慢慢欣赏arm64内核启动6 primary_entry之el2_setup代码第四部分。

shipinsky的博客 557

慢慢欣赏arm64内核启动23 primary_entry之__cpu_setup代码第五部分

CONFIG_ARM64_HW_AFDBM 是 Linux 内核的一个配置选项,用于启用 ARMv8.1 架构扩展中的硬件功能,该功能支持硬件更新页面表项中的访问(Access)和脏(Dirty)标志位。同样,如果向设置了 DBM 位的只读页面写入,将清除只读位(AP[2]),而不是触发权限故障。当在 TCR_EL1 寄存器(HA 和 HD 位)上启用此功能时,如果访问了清除了 PTE_AF 位的页面,则会设置该位,而不是触发访问标志故障。第2行到第6行为注释,含义为使能“硬件访问标记位”。

shipinsky的博客 879

慢慢欣赏arm64内核启动5 primary_entry之el2_setup代码第三部分

解析完虚拟化部分,我们继续分析启动过程中,对中断控制器的处理。

shipinsky的博客 814

慢慢欣赏arm64内核启动3 primary_entry之el2_setup代码第一部分

分析完el2_setup的注释和代码段的位置之后,我们正式开始学习el2_setup的实现。

shipinsky的博客 423

慢慢欣赏arm64内核启动21 primary_entry之__cpu_setup代码第三部分

展示代码 /* * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for * both user and kernel. */ mov_q x10, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ TCR_TBI0 | TCR_A1 | TC

shipinsky的博客 1277

慢慢欣赏arm64内核启动19 primary_entry之__cpu_setup代码第一部分

也就是说,位域bit12设置为1时,在EL0异常等级下,访问 MDCCSR_EL0, DBGDTR_EL0, DBGDTRTX_EL0, and DBGDTRRX_EL0 将会切换到 EL1 异常等级。第14, 15行涉及的寄存器 CPACR_EL1, Architectural Feature Access Control Register 的位域 bits[21:20]daifclr 涉及到 pstate 寄存器的 bits[9:6],分别是 DAIF,8对应 bit[9],表示清除调试掩码。

shipinsky的博客 1130

慢慢欣赏arm64内核启动24 primary_entry之__cpu_setup代码第六部分

第1行到第3行是注释,准备寄存器 SCTLR,SCTLR 是什么东东我们继续分析。第4行涉及宏定义 SCTLR_EL1_SET,定义如下。

shipinsky的博客 1199

慢慢欣赏arm64内核启动22 primary_entry之__cpu_setup代码第四部分

在该宏定义里面,ID_AA64MMFR0_EL1, AArch64 Memory Model Feature Register 0。第4行涉及到宏定义 tcr_compute_pa_size 和 TCR_IPS_SHIFT。提供 EL1 异常模式下 内存模型和内存管理的信息,涉及到的宏定义如下。第1到第3行是注释,含义是设置 TCR_EL1 的 IPS 域。其中,tcr_compute_pa_size 的定义如下。我们可以看到 bit[3] 始终为0, 所以可以忽略掉。

shipinsky的博客 891

手撕ARM64启动栈(一):QEMU + TF-A → OP-TEE → U-Boot → Linux 全链路总览

ARM 官方提供的参考固件实现,本文用作 BL1/BL2/BL31:开源 TEE 实现,本仓库用作 BL32,运行在 S-EL1,通过 opteed(SPD)与 BL31 交互,提供 TA 运行环境U-Boot:本仓库用作 BL33/Normal World bootloader,通过 ARM semihosting(,非网络/非fw_cfg)从宿主机文件系统读取内核与 initrd,bootm跳转内核。

Fifty的博客 496
上一篇: 慢慢欣赏arm64内核启动8 primary_entry之el2_setup代码第六部分
下一篇: 慢慢欣赏arm64内核启动10 primary_entry之set_cpu_boot_mode_flag
天麓
博客等级 码龄22年 323粉丝 437原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值