QEMU ARM64 全流程编译与运行指南(BL1→BL2→BL31→BL32→Linux)
本文基于 QEMU virt 平台 + ARM64 架构,一步步编译出 BL1/BL2/BL31/BL32 全套固件,跑通完整的 TrustZone 可信启动链,最终和已有的 Linux 终端环境打通。全程对应启动阶段理论。
一、前置准备:环境与源码
1. 安装系统依赖与工具链
在你的 Ubuntu 主机终端执行:
# 安装基础编译依赖
sudo apt update
sudo apt install -y build-essential git bison flex python3 python3-pip \
libssl-dev device-tree-compiler gcc-aarch64-linux-gnu \
qemu-system-arm qemu-utils
# 安装 OP-TEE 编译必需的 Python 库
pip3 install pyelftools pycryptodome
安装qemu-system-aarch64,我目前使用版本是QEMU emulator version 7.2.0

2. 下载源码并切换稳定版本
建议用固定稳定版本,避免最新主分支的兼容性问题:
# 1. 下载 ATF(ARM Trusted Firmware-A,提供 BL1/BL2/BL31)
git clone https://github.com/ARM-software/arm-trusted-firmware.git
# 2. 下载 OP-TEE OS(作为 BL32 安全世界 TEE)
git clone https://github.com/OP-TEE/optee_os.git
# 3. 下载 U-Boot(作为 BL33 正常世界引导程序)
git clone https://gitlab.denx.de/u-boot/u-boot.git
二、分步编译各阶段镜像
编译顺序:U-Boot(BL33)→ OP-TEE OS(BL32)→ ATF(打包全部镜像)
原因:ATF 编译时需要把 BL32、BL33 打包进 FIP 固件包,所以要先编译好后两个。
1. 编译 U-Boot(对应 BL33:正常世界引导程序)
BL33 是非安全世界的入口,对应真实产品里的 bootloader,这里用 U-Boot 实现。
cd u-boot
# 加载 QEMU ARM64 默认配置
make qemu_arm64_defconfig
# 交叉编译,-j 后跟 CPU 核心数加速
make CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
cd ..

2. 编译 OP-TEE OS(对应 BL32:安全世界 TEE 操作系统)
BL32 就是安全世界的 TEE 内核,对应我们之前讲的 OP-TEE OS。
注意:OP-TEE 的 ARCH 变量填 arm,通过 CFG_ARM64_core=y 开启 64 位,不能直接写 ARCH=arm64
cd optee_os
make PLATFORM=vexpress-qemu_armv8a \
ARCH=arm \
CFG_ARM64_core=y \
CROSS_COMPILE64=aarch64-linux-gnu- \
-j$(nproc)
cd ..
编译完成后,核心 BL32 产物:
optee_os/out/arm-plat-vexpress/core/tee-pager_v2.bin

3. 编译 ATF(生成 BL1/BL2/BL31,打包 FIP 固件包)
ATF 会生成 BL1、BL2、BL31,同时把 BL32(OP-TEE)、BL33(U-Boot)打包进 FIP 固件包。
必须加 SPD=opteed:编译 OP-TEE 专属的安全负载分发器,否则 ATF 不会加载 BL32。
cd arm-trusted-firmware
make PLAT=qemu \
ARCH=aarch64 \
CROSS_COMPILE=aarch64-linux-gnu- \
SPD=opteed \
BL32=../optee_os/out/arm-plat-vexpress/core/tee-pager_v2.bin \
BL33=../u-boot/u-boot.bin \
all fip
cd ..

编译产物说明(关键)
所有产物都在 arm-trusted-firmware/build/qemu/release/ 目录下:
|
文件名
|
对应阶段
|
说明
|
|
bl1.bin
|
BL1
|
第一阶段引导,对应芯片 BootROM,QEMU 直接加载运行
|
|
bl2.bin
|
BL2
|
第二阶段可信引导,已打包进 fip.bin
|
|
bl31.bin
|
BL31
|
EL3 运行时固件,已打包进 fip.bin
|
|
fip.bin
|
固件包
|
包含 BL2 + BL31 + BL32 + BL33,BL1 会加载并解析它
|

三、QEMU 启动完整可信启动链
1. 最简启动:验证固件全链路(BL1→BL2→BL31→BL32→BL33)
先不加载 Linux,先确认整个固件链能正常跑通,进入 U-Boot 命令行:
qemu-system-aarch64 \
-M virt,secure=on \
-cpu cortex-a57 \
-smp 2 \
-m 1024 \
-nographic \
-bios arm-trusted-firmware/build/qemu/release/bl1.bin \
-device loader,file=arm-trusted-firmware/build/qemu/release/fip.bin,addr=0x40000
关键参数解释
- -M virt,secure=on:必须加,开启 QEMU 的 TrustZone 安全扩展支持,不加则安全世界无法运行
- -bios bl1.bin:指定 BL1 作为启动 ROM,系统上电第一个执行的代码
- -device loader:把 FIP 固件包加载到物理地址 0x40000,BL1 会自动从这个地址读取并解析 FIP
2. 正常启动输出验证
启动后串口会按顺序打印以下信息,对应我们之前讲的启动阶段:
- BL1 阶段:打印 BL1: Booting BL2,表示 BL1 校验并加载 BL2 成功
- BL2 阶段:打印 BL2: Booting BL31,表示 BL2 校验并加载 BL31、BL32、BL33 成功
- BL31 阶段:打印 BL31: Initializing runtime services,表示 EL3 固件初始化完成
- BL32(OP-TEE)阶段:打印 OP-TEE version: 3.22.0 等字样,表示安全世界 TEE OS 启动成功
- BL33(U-Boot)阶段:进入 U-Boot 命令行,出现 => 提示符

看到这 5 步打印,就说明整个 BL 启动链 + TrustZone 安全世界已经完全跑通了。

360

被折叠的 条评论
为什么被折叠?



