ATF-源码分析-el3_exit 退出后跳转 8 种不同的目标场景
2026/6/3 17:14:35 网站建设 项目流程

el3_exit 退出后跳转 8 种不同的目标场景

el3_exit 本质上是一个 "世界切换引擎",它从 context 结构中取出 ELR_EL3(目标地址)和 SPSR_EL3(目标异常级别和 PSTATE),然后用 ERET 跳过去。跳到哪里完全取决于之前谁填了 context。

核心数据结构

在函数cm_setup_context(ctx, ep)中

write_ctx_reg(state, CTX_ELR_EL3, ep->pc); // ← 目标 PC write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr); // ← 目标 EL + PSTATE write_ctx_reg(state, CTX_SCR_EL3, scr_el3); // ← 安全状态 (S/NS/Realm)

场景 1:BL1 冷启动 → BL2(正常启动路径)

调用点: bl1_entrypoint.S

bl1_main() → bl1_prepare_next_image(BL2_IMAGE_ID) ↓ cm_init_my_context(next_bl_ep); ↓ cm_get_context(GET_SECURITY_STATE(ep->h.attr)); ↓ cm_setup_context(ctx, ep); ↓ write_ctx_reg(reg_ctx, CTX_SCR, scr); write_ctx_reg(reg_ctx, CTX_LR, ep->pc); write_ctx_reg(reg_ctx, CTX_SPSR, ep->spsr); ep->pc = BL2 入口地址 (从 FIP 加载的镜像头中读取) ep->spsr = BL2 目标异常级 (S-EL1 或 EL2) ↓ cm_prepare_el3_exit(security_state);

编译选项

SPSR_EL3 目标 EL

ERET 后

BL2 所在位置

!BL2_RUNS_AT_EL3

且BL32不存在

S-EL1

降级到 Secure-EL1

Secure RAM

!BL2_RUNS_AT_EL3

且BL32存在

EL2(NS)

降级到 Non-Secure EL2

Secure RAM

BL2_RUNS_AT_EL3

EL3(不走 el3_exit)

不降级(走bl1_run_bl2_in_el3)

Trusted SRAM

关键: bl1_prepare_next_image() 在 bl1/bl1_main.c被调用,它调用 cm_init_context() 把 BL2 的入口信息写入 context,然后 el3_exit 取出做 ERET。

场景 2:BL1 SMC 异常处理 → 返回调用者或跳转新镜像

调用点: bl1_exceptions.S

SMC 进入 → prepare_el3_entry (保存现场) → bl1_smc_wrapper_aarch64 → bl1_smc_handler → 处理完后 b el3_exit

SMC 类型

行为

ELR_EL3 目标

BL1_SMC_CALL_COUNT

/

BL1_SMC_UID

/

BL1_SMC_VERSION

直接返回

回到 SMC 发起者(ELR 未改)

FWU SMC(固件更新)

可能触发跳转下一阶段

下一阶段 BL 入口

典型场景: BL1 在 Firmware Update 模式下收到 SMC,处理完可能需要加载并跳转到新的 BL 镜像,此时 SMC handler 内部会调用 bl1_prepare_next_image() 改写 context,然后 el3_exit 跳转到新镜像。

场景 3:BL31 次 CPU 热启动 → 回到操作系统

调用点: bl31_entrypoint.S

PSCI CPU_ON 唤醒次 CPU → bl31_entrypoint → el3_entrypoint_common → 恢复 context → b el3_exit

ELR_EL3:之前 cm_setup_context_by_index() 设置的 NS 世界入口(即 OS 指定的启动地址)SPSR_EL3:= Non-Secure EL1 或 EL2(AArch64)SCR_EL3.NS:= 1(Non-Secure)→ 结果:退到 OS,CPU 从 OS 指定的入口开始执行

场景 4:BL31 SMC 处理完成 → 返回 Non-Secure 世界

调用点: runtime_exceptions.S

NS 世界发 SMC → trap 到 EL3 → handle_sync_exception → prepare_el3_entry (保存 NS 上下文) → handler_sync_exception (路由到 PSCI/SIP/SPD 等) → no_ret el3_exit

这是 最常见的路径。根据 SMC 功能号不同:

SMC 类型

目标

说明

PSCI_VERSION/PSCI_FEATURES

返回 NS 世界

ELR_EL3 = SMC 下一条指令,SPSR = NS-EL1/EL2

PSCI_CPU_SUSPEND

返回 NS 世界

不同入口

ELR_EL3 被改写为 OS 的唤醒入口地址

PSCI_SYSTEM_OFF

不返回

关机循环

SIP/SiP SMC

返回 NS 世界

ELR 未改 → 回到 SMC 发起者

场景 5:BL31 IRQ/FIQ 中断处理完成 → 返回低权限级

调用点: runtime_exceptions.S

中断类型

目标世界

说明

NS 中断(在 NS 世界触发)

返回 NS 世界

正常返回,ELR 不变

S-EL1 中断(在 Secure 世界触发)

返回 Secure 世界

可能触发世界切换

EL3 中断

EL3 自身处理

不走 el3_exit

场景 6:SPD 安全世界切换 → 跳入 Secure Partition

调用点: 各 SPD helper 文件末尾

SPD名称 文件 目标 ────── ────────────── ───────────── OP-TEE services/spd/opteed/opteed_helpers.S:42 OP-TEE OS (S-EL1) TSP services/spd/tspd/tspd_helpers.S:42 TSP (S-EL1) TLK services/spd/tlkd/tlkd_helpers.S:44 Trusted Little Kernel (S-EL1) PNC services/spd/pncd/pncd_helpers.S:42 PNC Secure Partition (S-EL1) Trusty services/spd/trusty/trusty_helpers.S:65 Trusty OS (S-EL1) SPM services/std_svc/spm/.../spm_helpers.S:41 S-EL0 Secure Partition SPMD services/std_svc/spmd/.../spmd_helpers.S:41 S-EL2 Secure Partition RMMD services/std_svc/rmmd/.../rmmd_helpers.S:41 Realm World (R-EL2)

ELR_EL3 = Secure Partition 的入口点(或恢复点)

SPSR_EL3 = S-EL1 / S-EL2 / R-EL2

SCR_EL3 = Secure 或 Realm 状态

场景 7:SDEI 事件分发 → 跳入 SDEI 处理函数

调用点: sdei_dispatch.S

SDEI 事件 → EL3 异常处理 → setjmp 保存现场 → 修改 ELR_EL3 为 SDEI handler → el3_exit

ELR_EL3 = SDEI 事件处理函数地址(在 NS-EL1/EL2 的虚拟地址空间)SPSR_EL3 = NS-EL1 或 NS-EL2 SCR_EL3.NS = 1→ 结果:CPU 退到 NS 世界,跳入注册的 SDEI handler

场景 8:PSCI CPU 电源管理 → 返回 OS 唤醒入口

调用点: 各平台 plat_pm.c 通过 C 函数调用 cm_prepare_el3_exit → el3_exit

例如 plat/arm/css/common/css_pm.c 等:

PSCI CPU_SUSPEND → 平台电源管理 → 改写 context 中的 ELR_EL3 为唤醒地址 → el3_exit

ELR_EL3 = psci_entrypoint(OS 指定的 CPU 唤醒入口)SPSR_EL3 = OS 的异常级别→ 结果:CPU 从电源管理状态恢复后直接进入 OS

全景图:所有 el3_exit 跳转目标汇总

el3_exit (ERET) │ ┌────────────────┼─────────────────────────┐ │ │ │ BL1 场景 BL31 场景 SPD/SECURE 场景 │ │ │ ┌─────┴────┐ ┌─────┴──────┐ ┌──────────────┴──────────────┐ │ │ │ │ │ │ │ BL2入口 SMC返回 NS世界 同步SMC 中断返回 S-EL1分区 Realm/R-EL2 (S-EL1/ (调用者 (OS 返回NS (IRQ/FIQ/ (OP-TEE, (RMMD) EL2) ) 唤醒入口) 世界 SError) TSP等)
关键结论:
  • el3_exit 只是一个"上下文恢复 + ERET"的机械执行器——跳到哪里完全取决于 之前谁往 context 的 CTX_ELR_EL3 和 CTX_SPSR_EL3 填了什么值
  • 它可以降级(EL3→EL2/EL1),也可以同级(SPSR 指向 EL3 时实为在同一级跳转)
  • 安全状态由 SCR_EL3 的 NS/NSE 位决定:0=Secure、1=Non-Secure、2=Realm

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询