2. ATF启动流程详解:从BL1到BL31的完整启动链路与各阶段职责
ARM Trusted Firmware (ATF) 是嵌入式Linux快速启动的基石。本章将深入剖析从BL1到BL31的完整启动链路,明确每个启动阶段(Boot Level)的核心职责、数据流与切换条件。理解这一链路是后续进行启动优化、裁剪与测量时间的关键前提。
2.1 ATF启动阶段总览
ATF将安全世界的启动划分为四个连续的阶段:BL1、BL2、BL31,以及可选的BL32(Trusted OS)。每个阶段运行在不同的异常级别(Exception Level),拥有独立的代码段、栈空间和MMU配置。下表总结了各阶段的核心属性:
| 阶段 | 异常级别 | 物理存储位置 | 核心职责 | 执行后跳转目标 |
|---|---|---|---|---|
| BL1 | EL3 | ROM (BootROM) | 最早期初始化、平台配置、加载BL2 | BL2入口 |
| BL2 | S-EL1 | Flash / eMMC | 加载BL31、BL32、BL33镜像,构建内存布局 | BL31入口 |
| BL31 | EL3 | DRAM | 运行时服务、中断管理、PSCI、安全监控 | BL32 / BL33入口 |
| BL32 (可选) | S-EL1 | DRAM | 可信操作系统(如OP-TEE) | BL33入口 |
| BL33 | EL2 / EL1 | DRAM | 非安全世界引导程序(如U-Boot、UEFI) | OS内核 |
2.2 BL1:ROM固件与最早期初始化
BL1是系统上电或复位后执行的第一段代码,通常存储在芯片内部的BootROM中。其执行环境极为受限:无DRAM、无栈、无MMU。BL1必须在极小的SRAM或Cache-as-RAM中完成初始化。
BL1核心流程
- 架构初始化: 设置异常向量表、配置系统控制寄存器(SCR_EL3、SCTLR_EL3)、初始化通用计时器。
- 平台初始化: 配置UART(早期调试输出)、时钟、电源管理单元(PMU)基础寄存器。
- 加载BL2: 从Flash指定偏移读取BL2镜像,验证其签名(如果使能Trusted Board Boot),然后拷贝到SRAM或预先保留的DRAM区域。
- 跳转: 清理缓存、设置BL2的入口参数(如平台ID、内存信息),执行ERET切换到BL2。
2.3 BL2:安全世界加载器
BL2运行在安全-EL1(S-EL1),拥有比BL1更丰富的执行环境。此时DRAM通常已经初始化完毕,BL2可以将后续镜像加载到DRAM中。BL2是ATF启动链中唯一负责“加载”其他所有镜像的阶段。
BL2核心职责
- 解析FIP(Firmware Image Package): 从Flash读取FIP表,定位BL31、BL32、BL33镜像的偏移与大小。
- 认证镜像: 如果使能TBBR(Trusted Board Boot Requirements),使用公钥验证每个镜像的数字签名。
- 构建内存布局: 为BL31、BL32、BL33分配DRAM区域,确保非安全世界无法访问安全内存。
- 传递平台参数: 将平台配置信息(如内存大小、GIC基址)通过寄存器或共享内存传递给BL31。
2.4 BL31:EL3运行时固件
BL31是ATF启动链中最重要的阶段,它驻留在EL3,负责管理安全世界与非安全世界之间的上下文切换。一旦BL31初始化完成,它将不再主动执行代码,而是作为“安全监控器”等待异常(SMC、IRQ、FIQ)触发。
BL31初始化流程
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 设置EL3运行时栈 | 为异常处理提供独立的栈空间 |
| 2 | 初始化中断控制器(GIC) | 配置安全中断与组0/组1路由 |
| 3 | 注册运行时服务 | PSCI、SIP(SiP Service)、TOS(Trusted OS Service) |
| 4 | 配置系统计数器 | 确保非安全世界可读取安全计数器 |
| 5 | 跳转到BL32或BL33 | 根据配置选择进入Trusted OS或直接启动非安全引导程序 |
2.5 BL32与BL33:安全OS与非安全引导
BL32(可选)是可信操作系统,如OP-TEE、Trusty。它运行在S-EL1,提供安全服务(如密钥管理、安全存储)。BL33则是非安全世界的引导程序,通常是U-Boot或UEFI固件,运行在EL2(虚拟化)或EL1(非虚拟化)。
启动链切换时序
BL1 → BL2 → BL31 → BL32 → BL33 → Linux Kernel
↓
(可选) 直接跳转 BL33
如果系统不需要Trusted OS,BL31在完成初始化后直接跳转到BL33。此时BL31仍然驻留在EL3,为后续的PSCI调用(如CPU_OFF、SYSTEM_SUSPEND)提供服务。
2.6 启动链路中的关键数据结构
ATF使用entry_point_info结构体在阶段间传递参数。该结构体包含入口地址、SPSR(Saved Program Status Register)、以及平台定义的上下文信息。
/* 摘自 include/lib/psci/psci.h */
typedef struct entry_point_info {
uintptr_t pc; /* 入口地址 */
uint32_t spsr; /* 目标异常级别 */
uint32_t args[4]; /* 通用参数寄存器 */
uint32_t context_id; /* 上下文标识 */
} entry_point_info_t;
在BL2跳转到BL31时,会将BL31的entry_point_info写入寄存器X0~X3。BL31解析这些参数后,再为BL32或BL33构造新的entry_point_info。
2.7 本章小结
- ATF启动链严格遵循BL1→BL2→BL31→(BL32)→BL33的顺序,每个阶段运行在特定的异常级别。
- BL1是ROM固件,负责最早期初始化和加载BL2;BL2是加载器,负责加载所有后续镜像;BL31是EL3运行时固件,提供安全监控服务。
- BL32(Trusted OS)为可选阶段,BL33是非安全引导程序,最终启动Linux内核。
- 理解每个阶段的职责与数据传递方式,是进行启动时间测量与优化的基础。