6.4 BL2到BL31/BL33的切换
目录
- 1. 切换过程概述
- 2. 镜像加载与验证
- 2.1 镜像加载流程
- 2.2 安全验证机制
- 3. 执行环境准备
- 3.1 BL31参数传递
- 3.2 内存布局配置
- 4. 控制权移交
- 4.1 切换执行流程
- 4.2 模式切换细节
- 5. 平台特定处理
- 5.1 平台回调函数
- 5.2 常见平台差异
- 6. 调试与问题排查
- 6.1 常见问题
- 6.2 调试技巧
- 7. 安全考量
- 附录:相关代码路径
1. 切换过程概述
BL2到BL31/BL33的切换是TF-A启动流程中的关键阶段,标志着:
- 完成可信固件初始化(BL31)
- 准备跳转到非安全世界(BL33,通常是Bootloader或Hypervisor)
典型切换流程:
- BL2加载BL31和BL33镜像到内存
- 验证镜像完整性和签名
- 初始化BL31执行环境
- 通过SMC调用将控制权移交BL31
- BL31接管后初始化EL3运行时服务
- 最终由BL31启动BL33
2. 镜像加载与验证
2.1 镜像加载流程
// 典型BL2加载逻辑(简化示例)
load_image(BL31_IMAGE_ID, bl31_ep_info);
load_image(BL33_IMAGE_ID, bl33_ep_info);// 验证镜像签名
auth_mod_verify_img(BL31_IMAGE_ID);
auth_mod_verify_img(BL33_IMAGE_ID);
关键数据结构:
bl31_ep_info
:包含BL31入口点、执行状态(AArch32/AArch64)、安全状态等bl33_ep_info
:包含BL33(通常是非安全EL2或EL1)的入口信息
2.2 安全验证机制
- 使用TF-A内置的认证模块(如mbedTLS)
- 支持多种签名算法(RSA/ECDSA/EdDSA)
- 证书链验证(CoT:Chain of Trust)
3. 执行环境准备
3.1 BL31参数传递
BL2通过寄存器传递关键参数给BL31:
x0
:指向BL31参数的指针x1
:指向BL33参数的指针x2
:平台特定上下文指针
参数结构示例:
struct bl31_params {bl31_ep_info_t bl31_ep_info;bl33_ep_info_t bl33_ep_info;uintptr_t plat_params;
};
3.2 内存布局配置
关键内存区域:
- BL31代码段(通常位于安全SRAM)
- BL33加载地址(取决于平台规范)
- 共享内存区域(用于BL31-BL33通信)
典型内存映射:
0x00000000 +-------------------+| BL33 (Non-secure) |
0x80000000 +-------------------+| BL31 (Secure EL3) |
0xFF000000 +-------------------+| Shared Memory |
0xFFFFFFFF +-------------------+
4. 控制权移交
4.1 切换执行流程
// BL2最后执行的代码(简化)
mov x0, bl31_params_ptr // 参数指针
mov x1, bl33_params_ptr
mov x2, plat_params_ptr
bl bl31_entrypoint // 跳转到BL31
4.2 模式切换细节
- 从BL2(EL1/EL3)切换到BL31(EL3)
- 安全状态保持(始终在安全世界)
- 可能涉及执行状态切换(AArch32 ↔ AArch64)
5. 平台特定处理
5.1 平台回调函数
// 平台可实现的回调
void bl2_plat_handle_bl31(const image_info_t *bl31_image_info);
void bl2_plat_handle_bl33(const image_info_t *bl33_image_info);
5.2 常见平台差异
平台特性 | ARM FVP | Juno | 自定义SoC |
---|---|---|---|
BL31加载地址 | 0x04000000 | 0x80000000 | 平台定义 |
BL33入口类型 | EL2 (Hypervisor) | EL1 (Bootloader) | 可配置 |
共享内存基址 | 0x0403F000 | 0x0403F000 | DT定义 |
6. 调试与问题排查
6.1 常见问题
-
镜像加载失败:
- 检查BL31/BL33镜像地址是否正确
- 验证内存区域是否可写
-
验证失败:
- 确认证书链配置正确
- 检查签名算法是否匹配
-
切换后崩溃:
- 检查执行状态(AArch32/64)是否一致
- 验证BL31参数传递是否正确
6.2 调试技巧
# 使用TF-A调试宏
NOTICE("BL2: BL31 ep=0x%lx, BL33 ep=0x%lx\n",bl31_ep_info->pc, bl33_ep_info->pc);# QEMU调试命令
(gdb) b bl31_entrypoint
(gdb) x/10i $pc
7. 安全考量
-
完整性保护:
- 所有跳转地址必须经过验证
- 禁止修改已验证的代码区域
-
机密性保护:
- 安全参数在传递过程中应加密
- 清除BL2敏感数据(如临时密钥)
-
防回滚:
- 检查BL31/BL33版本号
- 验证抗回滚计数器
附录:相关代码路径
- BL2主流程:
bl2/bl2_main.c
- 镜像加载:
common/image_loader.c
- BL31入口:
bl31/bl31_entrypoint.S
- 平台实现:
plat/<platform>/bl2_plat_setup.c