2. 开发环境搭建:硬件平台、交叉编译链、调试器与固件依赖
在构建 TrustZone 安全世界初始化固件之前,必须完成贯穿开发、编译、调试、运行全周期的环境搭建。本章按四个子专题组织:硬件平台选择(QEMU 与 FPGA 的取舍)、交叉编译链安装与验证、调试器接入方式(JTAG/SWD / GDB)以及 TrustZone 固件依赖(ATF、OP-TEE、U-Boot 等)。
推荐起点:初学者及原型验证阶段优先使用 QEMU;FPGA 适用于硬件时序验证与最终性能调优。本章以 QEMU 为默认平台给出所有命令行示例。
2.1 硬件平台选择:QEMU 与 FPGA 对比
| 维度 | QEMU(软件仿真) | FPGA(硬件原型) |
|---|---|---|
| 启动速度 | 秒级,适合快速迭代 | 分钟级(综合+布局布线) |
| 硬件精确度 | 指令级仿真,外设模型有限 | 精确到时钟周期,真实外设时序 |
| 调试能力 | 原生 GDB stub,断点/单步 | JTAG + 硬件调试器,支持实时追踪 |
| 成本 | 免费,无硬件开销 | 开发板 $200–$2000+ |
| 适用阶段 | 功能验证、安全世界初始化流程 | 驱动集成、性能优化、安全攻击测试 |
本课程所有代码与寄存器配置均针对 QEMU virt-8.2+ 平台,并额外标注与 FPGA 的差异点。
2.2 交叉编译链安装与验证
TrustZone 安全世界运行于 AArch64 状态(Cortex-A53/A72),必须使用 aarch64-none-elf- 或 aarch64-linux-gnu- 工具链。推荐版本为 ARM GCC 13.2.Rel1。
# 下载并解压
wget https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-aarch64-none-elf.tar.xz
tar -xf arm-gnu-toolchain-13.2.rel1-x86_64-aarch64-none-elf.tar.xz
mv arm-gnu-toolchain-13.2.rel1-x86_64-aarch64-none-elf /opt/arm-gcc-aarch64
# 设置环境变量
export PATH=/opt/arm-gcc-aarch64/bin:$PATH
# 验证编译与 objdump
aarch64-none-elf-gcc -v 2>&1 | head -n 1
aarch64-none-elf-objdump -i
关键区别:
aarch64-none-elf- 不依赖 libc,适合裸机/BL1/BL2 固件;aarch64-linux-gnu- 用于 Linux 内核与 OP-TEE OS 编译。安全世界初始化代码属于裸机环境,优先使用 none-elf 前缀。
2.3 调试器接入方式(JTAG / SWD / GDB)
QEMU 内置 GDB stub 提供与硬件调试器几乎一致的体验。FPGA 开发板需外接 JTAG/SWD 调试器(如 SEGGER J-Link、ARM DStream)。
| 调试方式 | 协议 | 连接接口 | 典型工具 |
|---|---|---|---|
| QEMU GDB Stub | TCP | 网络(localhost:1234) | aarch64-none-elf-gdb |
| JTAG | IEEE 1149.1 | 20-pin 盒带 | OpenOCD + GDB |
| SWD | ARM 专用 | 2线(SWDIO+SWCLK) | pyOCD / J-Link Commander |
启动 QEMU 并附加调试器(单核 Cortex-A53):
qemu-system-aarch64 -machine virt -cpu cortex-a53 -smp 1 \
-m 1024 -nographic -bios bl1.bin \
-gdb tcp::1234 -S
参数 -S 让 CPU 在第一条指令处暂停,等待 GDB 连接。然后在另一个终端启动 GDB:
aarch64-none-elf-gdb bl1.elf
(gdb) target remote :1234
(gdb) info registers x0 x1 x2
(gdb) break bl1_entry
(gdb) continue
常见错误:QEMU 的
-bios 参数仅加载原始二进制文件,-kernel 则会自动将 Image 放入 DRAM 并设置启动参数。安全世界初始化阶段应使用 -bios,避免 QEMU 干扰 EL3 入口状态。
2.4 TrustZone 固件依赖关系
安全世界初始化并非单一固件,而是至少涉及三个软件组件的协作:
- ARM Trusted Firmware-A(TF-A):提供 BL1、BL2、BL31,负责安全监视器、PSCI、中断路由。
- OP-TEE:提供安全世界 OS(BL32),运行于 S-EL1,支持 TA 加载。
- U-Boot(可选):作为 BL33 进入非安全世界,加载 Linux 内核。
典型构建链只需 TF-A + OP-TEE 即可完成安全世界初始化。下表给出最小依赖及其推荐版本:
| 组件 | GIT 仓库 | 推荐分支 / Tag |
|---|---|---|
| TF-A | https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git | v2.10.0 |
| OP-TEE OS | https://github.com/OP-TEE/optee_os.git | 4.2.0 |
| QEMU | https://gitlab.com/qemu-project/qemu.git | v8.2.0 |
# 克隆 TF-A
git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git -b v2.10.0
# 克隆 OP-TEE OS
git clone https://github.com/OP-TEE/optee_os.git -b 4.2.0
# 为 QEMU 构建 TF-A(仅 BL1 + BL2 + BL31)
cd trusted-firmware-a
make CROSS_COMPILE=aarch64-none-elf- PLAT=qemu DEBUG=1 bl1 bl2 bl31
输出产物:
build/qemu/debug/bl1.bin、bl2.bin、bl31.bin,以及 ELF 调试文件 bl1/bl2/bl31.elf。这些 .bin 通过 QEMU 的 -bios 以及后续的 fip 打包工具组合成一个 FIP 映像。
2.5 完整验证:启动并观察安全世界初始化输出
将 TF-A 与 OP-TEE OS 合并为 FIP 映像,并用 QEMU 加载:
# 构建 OP-TEE OS(需指定 PLATFORM)
cd optee_os
make PLATFORM=vexpress-qemu_armv8a CROSS_COMPILE64=aarch64-none-elf- CFG_ARM64_core=y O=out
# 返回 TF-A 构建 FIP(合并 BL2、BL31、BL32)
cd ../trusted-firmware-a
make CROSS_COMPILE=aarch64-none-elf- PLAT=qemu DEBUG=1 \
BL32=../optee_os/out/core/tee-pager_v2.bin \
fip
# 启动 QEMU
qemu-system-aarch64 -machine virt -cpu cortex-a53 -m 1024 -nographic \
-bios build/qemu/debug/bl1.bin \
-drive if=none,file=build/qemu/debug/fip.bin,format=raw,id=fip \
-device virtio-blk-device,drive=fip
观察初始化进度:QEMU UART 输出应依次显示 BL1(标记冷启动 / 晶振频率)、BL2(加载映像)、BL31(设置异常向量表)、OP-TEE(打印版本与 init 信息)。如 GIC 或定时器未正确配置,输出会在 BL31 处卡住或循环错误断言。
2.6 常见错误与诊断
- “NOTICE: BL31: Non‑secure world also cold‑booted” 消失:表明 BL31 未成功跳转到 BL32,检查 FIP 中 BL32 地址与构建时的
ARM_TSP_RAM_LOCATION。 - “E/TC: OP-TEE init failed at …”:OP-TEE 依赖安全 DRAM(如 0x4000000),与 QEMU 内存布局冲突时出现;检查 QEMU 启动参数中的
-m与 TF-AARM_LINUX_KERNEL_AS_BL33设定。 - GDB 无法连接至端口 1234:确认未启用
-sandbox on且防火墙未阻拦;改用localhost:1234明确 IP。 - 交叉编译链接时失败:将
CROSS_COMPILE改为完整路径/opt/arm-gcc-aarch64/bin/aarch64-none-elf-。
2.7 性能与稳定性优化初步
- 编译优化:
DEBUG=1包含大量断言与日志;切换到DEBUG=0并启用SPD=opteed可减少 30% 二进制体积及缩短启动时间。 - GIC 配置:QEMU 默认使用 GICv3,TF-A 构建时必须指定
GICV3_GICD_BASE=0x2f000000 GICV3_GICR_BASE=0x2f100000,否则安全世界中断无法到达目标 PE。 - 系统计数器:FPGA 平台需提供真实晶振频率(如 24 MHz),QEMU 自动仿真该频率,无需额外校准。
2.8 小结:环境评估清单
- 交叉编译链(aarch64-none-elf-gcc 13.2)已安装且
PATH有效。 - QEMU 8.2+ 支持
virt平台及 GICv3 模型。 - TF-A v2.10.0 与 OP-TEE 4.2.0 已克隆至本地,
make PLAT=qemu无报错。 - 能通过 QEMU UART 看到 BL1、BL2、BL31 与 OP-TEE 的启动日志。
- 可附加 GDB 并设置断点于
bl1_entry,单步跟踪第一条安全世界指令。
时序敏感陷阱:FPGA 平台若未正确配置
TIMER_CLK 或 GIC 基地址,BL31 中初始化系统计数器会挂死。QEMU 不暴露此类硬件敏感性,但需为 FPGA 单独准备 DTS 与配套头文件。