2. ATF启动流程详解:BL1、BL2、BL31、BL32、BL33的加载与执行、SP_MIN与TSPD

好,我们直接进入正题。ATF的启动流程,说白了就是ARM Trusted Firmware从复位到交出控制权给操作系统的一整套动作。很多初学者一上来就被BL1、BL2、BL31这些缩写搞晕了,其实没那么复杂。你把它想象成一个接力赛——每个阶段跑一段,跑完了把棒子交给下一棒。

我个人习惯把ATF启动分成五个阶段:BL1、BL2、BL31、BL32、BL33。每个阶段都有明确的职责和生命周期。下面我带你一个一个拆开看。

2.1 整体启动流程概览

先看一张总图,把整个流程串起来。这张图我画了很多次,每次给团队新人讲启动流程都会先贴出来。

ATF 启动流程总览 BL1 ROM Bootloader BL2 Trusted Boot BL31 EL3 Runtime BL32 TEE (OP-TEE) BL33 U-Boot/EDK2 关键说明: • BL1 在片上ROM中执行,不可修改 • BL2 负责加载后续镜像并验证签名 • BL31 是EL3常驻运行时,管理SMC和PSCI • BL32 是安全世界OS(如OP-TEE),通过TSPD与BL31交互 • BL33 是非安全世界Bootloader(U-Boot/EDK2)

嗯,这里要注意:BL1和BL2在完成使命后就不再运行了,它们的内存也会被回收。真正常驻的是BL31和BL32。BL33启动后,整个系统就进入了正常世界。

2.2 BL1:第一级启动加载器

BL1是系统上电后执行的第一段代码。它存储在片上ROM里,出厂就烧好了,你改不了。这也是整个信任链的根。

BL1的核心职责:

  • 初始化最基本的硬件(时钟、串口、DRAM控制器)
  • 从Flash/MMC加载BL2到SRAM
  • 验证BL2的签名(如果使能了认证链)
  • 跳转到BL2入口

我在项目中遇到过一个问题:某款芯片的BL1在DRAM初始化时踩了一个硬件坑——它的DRAM控制器需要先做一次dummy访问才能稳定。查了两天才定位到,最后在BL1的初始化序列里加了一个伪读取搞定。这种问题在芯片勘误表里经常有,但很少有人会提前看。

小技巧: 调试BL1时,建议在串口初始化后立即打印一个字符。这样你能确认BL1是否真的跑起来了。我习惯在BL1入口处打印一个"B1",在跳转到BL2前打印"B2"。就两个字符,但能帮你省下大量定位时间。

2.3 BL2:可信启动加载器

BL2运行在SRAM中,由BL1加载并验证。它的任务很明确:把剩下的镜像都准备好。

BL2的工作流程:

  1. 从存储设备读取镜像描述信息(FIP格式)
  2. 解析镜像列表,找到BL31、BL32、BL33的位置
  3. 逐个加载到内存,验证签名
  4. 配置内存布局,确保各镜像不重叠
  5. 跳转到BL31入口

你想想看,BL2其实就是一个微型的bootloader。它不负责运行操作系统,只负责把东西搬到该放的位置。搬完了,它的使命就结束了。

注意: BL2的内存空间会被BL31复用。所以BL2不能有任何全局变量在跳转后还需要访问。我曾经见过一个同事在BL2里开了个定时器中断,结果跳转到BL31后中断向量表变了,直接触发异常。这种问题很难查,因为现象是随机的。

2.4 BL31:EL3运行时固件

BL31是ATF的核心。它运行在EL3,是系统里权限最高的软件。一旦BL31启动,它就不会退出了——它会一直驻留,处理各种安全相关的请求。

BL31的主要功能:

功能模块 说明
SMC处理 接收来自正常世界和安全世界的SMC调用,路由到对应处理函数
PSCI 电源状态管理,包括CPU开关、挂起、系统重启等
中断管理 配置GIC,处理安全中断和普通中断的路由
TSPD Trusted Service Provider Dispatcher,负责与BL32通信

这里要重点说一下TSPD。它是BL31里的一个模块,专门用来对接BL32(也就是TEE)。TSPD做的事情说白了就是:当正常世界想调用TEE的服务时,它负责把SMC请求转发给BL32,再把结果返回给正常世界。

2.5 BL32:安全世界OS(TEE)

BL32就是我们课程的主角之一——OP-TEE。它运行在安全世界,提供安全服务。

BL32的加载方式:

  • BL2将BL32镜像加载到安全DRAM
  • BL31通过TSPD初始化BL32
  • BL32初始化完成后,进入等待状态
  • 当有SMC请求时,BL32被唤醒执行对应服务

我记得第一次调OP-TEE时,发现BL32启动后马上就panic了。查了半天,原来是安全DRAM的地址配置错了——BL2把镜像放到了非安全区域,BL31一跳过去就访问违例。这种问题在移植新平台时特别常见,一定要仔细核对内存地址映射。

2.6 BL33:非安全世界Bootloader

BL33就是正常世界的bootloader,通常是U-Boot或者EDK2。它运行在EL2或EL1,负责加载操作系统内核。

BL31在完成所有初始化后,会通过一条SMC指令将控制权交给BL33。从这一刻起,系统就进入了正常世界。但BL31并没有闲着——它还在EL3等着,随时准备处理来自正常世界的SMC请求。

2.7 SP_MIN与TSPD

这两个概念容易混淆,我单独拿出来讲。

SP_MIN 是ATF提供的一个最小化安全分区管理器。它适用于不需要完整TEE的场景。说白了,如果你只需要PSCI和基本的安全服务,不需要跑OP-TEE,那SP_MIN就够了。它体积小,启动快,但功能也有限。

TSPD 是BL31里的一个调度模块,专门用于对接TEE。它实现了以下功能:

  • 初始化TEE(BL32)
  • 转发SMC请求到TEE
  • 管理TEE的上下文切换
  • 处理TEE返回的结果

两者的选择很简单:用OP-TEE就选TSPD,不用就选SP_MIN。我在一个低功耗IoT项目里用过SP_MIN,因为那个芯片只有256KB SRAM,跑OP-TEE太勉强了。SP_MIN加上PSCI,刚好够用。

核心总结:
  • BL1 → BL2 → BL31 → (BL32) → BL33,这是标准启动链
  • BL31是常驻EL3的运行时,负责SMC、PSCI、中断路由
  • TSPD是BL31与BL32之间的桥梁
  • SP_MIN是TSPD的轻量替代方案,适用于无TEE场景

好了,这一章的内容就到这里。启动流程是ATF的基础,后面的章节我们会深入每个阶段的代码实现。你先把这张图印在脑子里,后面写代码时就知道自己在哪个阶段了。