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 编译选项