1. 搭建TrustZone开发环境
任务说明
本案例目标是在本机搭建一套可用的 ARM TrustZone 开发环境,覆盖工具链安装、模拟器/开发板支持包配置,并完成一次最小化的交叉编译与调试验证。TrustZone 本身依赖 ARM 硬件扩展,因此本环境以 QEMU + ARMv8-A 模拟器作为默认目标,同时保留开发板接入路径。
环境依赖
- 主机系统:Ubuntu 22.04 LTS(x86_64)或 WSL2 下同版本
- 必要软件包:
build-essential、git、python3、pkg-config、libglib2.0-dev、libpixman-1-dev - 交叉编译器:
gcc-aarch64-linux-gnu(用于编译 TrustZone 裸机/EL3 代码) - 模拟器:
qemu-system-aarch64(版本 ≥ 7.0,支持virt机器类型) - 调试器:
gdb-multiarch(用于连接 QEMU 的 GDB stub)
安装步骤
# 1. 安装基础依赖
sudo apt update
sudo apt install -y build-essential git python3 pkg-config libglib2.0-dev libpixman-1-dev
# 2. 安装交叉编译器与调试器
sudo apt install -y gcc-aarch64-linux-gnu gdb-multiarch
# 3. 安装 QEMU(若系统版本过旧,可自行源码编译)
sudo apt install -y qemu-system-arm
# 4. 验证安装
aarch64-linux-gnu-gcc --version
qemu-system-aarch64 --version
gdb-multiarch --version
最小可复现工程
创建一个仅包含 TrustZone 启动入口的裸机程序,用于验证编译、加载和调试链路。该程序在 EL3 异常级别执行,直接操作 SCR_EL3 寄存器以确认安全状态。
// tz_entry.c
// TrustZone 最小启动验证程序:在 EL3 读取并修改 SCR_EL3
__attribute__((naked)) void _start(void) {
__asm__ volatile(
"msr scr_el3, xzr\n" // 清零 SCR_EL3,禁用安全扩展干扰
"mrs x0, scr_el3\n" // 读回验证
"msr daifset, #0xf\n" // 屏蔽所有中断
"b .\n" // 死循环,便于调试观察
);
}
// 链接脚本:将代码加载到 QEMU virt 机器的 DRAM 起始地址
// tz.ld
// ENTRY(_start)
// SECTIONS {
// . = 0x40000000;
// .text : { *(.text) }
// .data : { *(.data) }
// .bss : { *(.bss) }
// }
编译与运行
# 编译为 ELF(使用 -nostdlib 避免依赖裸机库)
aarch64-linux-gnu-gcc -c tz_entry.c -o tz_entry.o
aarch64-linux-gnu-ld -T tz.ld tz_entry.o -o tz_entry.elf
# 转换为原始二进制(QEMU 直接加载)
aarch64-linux-gnu-objcopy -O binary tz_entry.elf tz_entry.bin
# 启动 QEMU(virt 机器,CPU 默认从 EL3 启动)
qemu-system-aarch64 -machine virt -cpu cortex-a57 \
-nographic -serial mon:stdio \
-device loader,file=tz_entry.bin,addr=0x40000000 \
-S -s
参数说明:-S 表示启动后暂停等待调试器;-s 在端口 1234 开放 GDB stub。
调试验证
# 另开终端,连接 GDB
gdb-multiarch tz_entry.elf
# 在 GDB 内执行:
# (gdb) target remote :1234
# (gdb) x/4i $pc → 应看到 _start 处的指令
# (gdb) si → 单步执行 msr scr_el3, xzr
# (gdb) p/x $scr_el3 → 应输出 0x0
# (gdb) si → 单步执行 mrs x0, scr_el3
# (gdb) p/x $x0 → 应输出 0x0,证明读写一致
# (gdb) continue → 程序进入死循环,CPU 停止在 b . 处
通过判定标准
- 编译阶段无报错,生成
tz_entry.elf与tz_entry.bin - QEMU 正常启动且不崩溃,GDB 能成功连接
- 单步执行后
SCR_EL3与x0均为 0,证明 EL3 下寄存器访问路径有效 - 若使用真实开发板(如 Raspberry Pi 4 的 ARM TrustZone 固件),仅需将
-machine virt替换为对应板卡支持包,并调整加载地址;本案例的交叉编译与调试流程不变
常见问题
- QEMU 提示无法加载 ELF:确认使用
-device loader加载原始二进制而非 ELF,或改用-kernel参数加载 ELF - GDB 无法连接:检查 QEMU 是否以
-s启动,且端口 1234 未被占用 - 编译报错缺少头文件:本工程不依赖任何头文件,若添加新代码需确保使用
-ffreestanding编译选项