3. 启动流程总览:从 ROM Code 到 TEE 内核的完整启动链路
这一章,我们来聊聊 TEE 的整个启动过程。说白了,就是设备上电后,从芯片内部固化的第一行代码开始,一直到 TEE 内核跑起来,这中间到底发生了什么。
我刚开始接触 TEE 时,觉得这东西就是个黑盒。后来调过几次启动日志,才慢慢摸清门道。你会发现,整个启动链路其实被分成了几个清晰的阶段。每个阶段都有明确的任务,也有各自的坑。
3.1 启动链路全景图
先给你一张总图,把整个流程串起来。这样你心里有个谱,后面再细看每个阶段时,就不会迷路。
核心要点:TEE 的启动是一个「逐级验证、逐级加载」的过程。每一级只信任上一级,上一级验证通过后,才把控制权交给下一级。这就是所谓的「信任链」。
3.2 关键阶段划分
整个启动链路,按 ARM Trusted Firmware (ATF) 的规范,被划分为几个 Boot Loader 阶段。每个阶段都有编号:BL1、BL2、BL31。OP-TEE 作为 TEE OS,在 BL31 之后加载。
| 阶段 | 名称 | 运行位置 | 主要职责 |
|---|---|---|---|
| ROM Code | 芯片固件 | 片上 ROM | 初始化硬件,加载 BL1 |
| BL1 | BootROM | SRAM | 验证 BL2,加载 BL2 |
| BL2 | 可信固件 | DRAM | 验证 BL31、OP-TEE、U-Boot |
| BL31 | EL3 Runtime | DRAM | 提供 Secure Monitor,切换世界 |
| OP-TEE | TEE OS | 安全 DRAM | 提供安全服务,运行 TA |
我的经验:调试启动问题时,我习惯先看日志里有没有打印 BL2 的版本号。如果连 BL2 都没跑起来,那问题大概率出在 BL1 或更早的硬件初始化上。别一上来就盯着 OP-TEE 的日志看,那会绕弯路。
3.3 逐级详解
3.3.1 ROM Code
这是芯片出厂时固化在 ROM 里的代码。你改不了它,也删不掉它。上电后,CPU 的第一条指令就从这里开始。
ROM Code 做的事很简单:
- 初始化最基本的硬件(时钟、SRAM、看门狗)
- 从 Boot Device(比如 eMMC、NAND Flash)读取 BL1
- 把 BL1 加载到 SRAM 中,然后跳转过去
嗯,这里要注意。ROM Code 本身不做任何安全验证。它只是机械地把 BL1 加载进来。真正的信任链,从 BL1 才开始。
3.3.2 BL1
BL1 是第一个可被信任的代码。它运行在 SRAM 里,空间非常有限。我见过有些芯片的 SRAM 只有 64KB,BL1 得精打细算才能塞进去。
BL1 的核心任务:
- 验证 BL2 的签名——用公钥检查 BL2 的镜像是否被篡改过
- 加载 BL2——把 BL2 从 Flash 复制到 DRAM 中
- 配置安全内存——设置 TrustZone 的内存保护
我曾经踩过的坑:有一次 BL1 总是验证 BL2 失败,日志里报签名错误。查了半天,发现是 Flash 里烧录的 BL2 镜像和 BL1 里硬编码的公钥不匹配。说白了,就是固件版本没对齐。从那以后,我每次烧录都会 double-check 公钥哈希值。
3.3.3 BL2
BL2 是可信固件的核心。它运行在 DRAM 里,空间比 BL1 宽裕多了。BL2 负责加载和验证后续所有的镜像。
BL2 做的事:
- 验证 BL31(EL3 Runtime)的签名
- 验证 OP-TEE OS 的签名
- 验证 U-Boot(或其它 Bootloader)的签名
- 配置安全和非安全世界的内存布局
你想想看,BL2 就像个安检员。所有要进入系统的代码,都得经过它的检查。它说不行,那就真不行。
3.3.4 BL31
BL31 是运行在 EL3(异常级别 3)的 Runtime 固件。EL3 是 ARM 架构里权限最高的级别,比安全世界和非安全世界都高。
BL31 的主要职责:
- 提供 Secure Monitor Call (SMC) 处理
- 负责安全世界和非安全世界之间的切换
- 管理电源状态(CPU 休眠、唤醒等)
说白了,BL31 就是个「看门人」。非安全世界想调用安全服务,得通过 SMC 指令先找 BL31,BL31 再转发给 OP-TEE。
3.3.5 OP-TEE OS
OP-TEE 是 TEE 的内核。它运行在安全世界里,提供安全服务。OP-TEE 启动后,会初始化安全内存、加载可信应用(TA)、注册 SMC 处理函数。
OP-TEE 启动日志里,你会看到类似这样的输出:
I/TC: OP-TEE version: 3.22.0
I/TC: Initialized
I/TC: SMC handler registered
I/TC: TA: supplicant ready
看到这三行,基本可以确认 OP-TEE 已经跑起来了。
3.4 信任链的传递
整个启动过程,核心就是信任链的传递。每一级都验证下一级的签名,确保没有被篡改。
信任链的传递路径:
- ROM Code(硬件信任根)→ 加载 BL1
- BL1(验证 BL2 签名)→ 加载 BL2
- BL2(验证 BL31、OP-TEE、U-Boot 签名)→ 加载各镜像
- BL31 → 启动 OP-TEE 和 Normal World
关键点:信任链的根是 ROM Code。ROM Code 是硬件固化的,无法被篡改。只要 ROM Code 是安全的,整个链条就是安全的。这就是「信任根」的概念。
3.5 启动日志中的关键线索
调试启动问题时,日志是你的第一手资料。我总结了几条关键线索,你可以对照着看:
| 日志内容 | 含义 | 常见问题 |
|---|---|---|
NOTICE: BL1: v2.8 |
BL1 启动成功 | 如果没看到,检查硬件或 Flash |
ERROR: BL2: image auth failed |
BL2 验证镜像签名失败 | 固件版本不匹配,或镜像损坏 |
I/TC: OP-TEE version: 3.22.0 |
OP-TEE 启动成功 | 如果没看到,检查 BL2 是否加载了 OP-TEE |
U-Boot: Starting kernel |
Normal World 启动 | 如果卡在这里,检查设备树配置 |
我的习惯:每次拿到新的开发板,我会先做一次「干净启动」——把日志全部抓下来,逐行对照。这样后面出了问题,才知道哪些是正常的,哪些是异常的。别偷懒,这个习惯能帮你省很多时间。
3.6 小结
这一章我们走完了 TEE 的完整启动链路。从 ROM Code 到 OP-TEE,每一级都有明确的分工。记住信任链的传递方式,这是理解 TEE 安全性的基础。