4. 开发环境搭建:QEMU模拟器环境搭建、OP-TEE源码编译、开发板环境准备

说实话,TEE开发最劝退人的地方,往往不是概念有多难,而是环境搭不起来。我见过太多同事卡在编译这一步,一卡就是两三天。所以这一章,咱们把环境搭建这件事彻底讲透。

我会从三个维度来讲:先用QEMU模拟器让你在笔记本上就能跑OP-TEE,再讲源码编译的细节,最后说说真机开发板的准备。你跟着走一遍,基本就能把环境跑通了。

核心思路:开发环境分三层——模拟器层(QEMU)、软件层(OP-TEE源码)、硬件层(开发板)。建议先搞定模拟器,再上真机。

TEE开发环境三层架构 TEE开发环境搭建 — 三层架构 QEMU模拟器层 ARM虚拟平台 OP-TEE软件层 源码编译 + 镜像 开发板硬件层 ARM真实芯片 推荐学习路径: ① 先在QEMU上跑通OP-TEE → ② 理解源码结构和编译流程 → ③ 再移植到真实开发板 这样做的最大好处:QEMU调试方便,出错了改代码快,不用反复烧写开发板。 我当年就是直接上开发板,结果每次编译都要等5分钟烧写,效率极低。

4.1 QEMU模拟器环境搭建

QEMU是什么?说白了就是一个软件模拟的ARM开发板。你不需要买任何硬件,就能在PC上跑ARM架构的Linux和OP-TEE。

我个人习惯用QEMU做前期开发,原因很简单:调试效率高。在QEMU上,你可以随时打断点、看内存、改代码,不用反复烧写Flash。

4.1.1 安装依赖包

先装好基础工具。以Ubuntu 20.04/22.04为例:

sudo apt-get update
sudo apt-get install -y \
    qemu-system-arm \
    qemu-user-static \
    gcc-arm-linux-gnueabihf \
    build-essential \
    git \
    python3-pip \
    libssl-dev \
    device-tree-compiler \
    u-boot-tools

小技巧:如果你用的是Ubuntu 22.04,QEMU版本默认是6.2,够用。但如果你需要更老的ARMv7支持,建议装7.2以上版本。我遇到过QEMU版本太低导致某些ARMv8扩展指令不支持的情况。

4.1.2 验证QEMU安装

qemu-system-arm --version
# 输出示例:QEMU emulator version 6.2.0

看到版本号就说明装好了。接下来我们测试一下能不能启动一个最小的ARM Linux内核。

# 下载测试内核
wget https://releases.linaro.org/components/kernel/uefi-linaro/5.10/release/qemu/qemu-system-aarch64.efi

# 启动测试
qemu-system-aarch64 -machine virt -cpu cortex-a57 \
    -m 1024 -nographic \
    -bios qemu-system-aarch64.efi

如果能看到UEFI Shell界面,恭喜你,QEMU环境已经通了。

注意:QEMU的machine参数很重要。OP-TEE官方推荐用 virt 或 vexpress-a15。我踩过坑——用错了machine类型,导致OP-TEE启动时SMC调用失败,查了两天才发现是虚拟硬件不匹配。

4.2 OP-TEE源码编译

OP-TEE的源码编译,是很多人觉得最头疼的部分。其实捋清楚了就三步:下载repo、配置环境、执行编译。

我记得第一次编译OP-TEE时,光下载源码就花了半小时,因为repo要同步好几个仓库。后来发现可以用 --depth=1 参数只拉最新代码,快很多。

4.2.1 下载OP-TEE源码

OP-TEE官方推荐用repo工具管理多仓库。先装repo:

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

然后初始化OP-TEE源码:

mkdir ~/optee
cd ~/optee
repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml
repo sync -j4 --depth=1

这里解释一下 qemu_v8.xml 是什么。它定义了一组仓库的版本组合,包括:

组件 仓库 作用
OP-TEE OS optee_os TEE内核,运行在安全世界
OP-TEE Client optee_client REE侧的用户态库,CA通过它调用TEE
OP-TEE Test optee_test 测试用例,验证TEE功能
Linux内核 linux REE侧操作系统,带OP-TEE驱动
ATF arm-trusted-firmware ARM可信固件,负责安全启动和SMC处理
U-Boot u-boot 引导加载程序

4.2.2 配置交叉编译工具链

OP-TEE需要交叉编译,因为你的PC是x86架构,而目标平台是ARM。我建议用官方预编译的工具链:

# 下载ARM64交叉编译工具链
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
tar -xf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
export PATH=$PWD/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH

避坑指南:我曾经用系统自带的gcc-arm-linux-gnueabihf编译OP-TEE,结果链接时报了一堆undefined reference。后来发现是工具链版本太老,不支持某些ARMv8.1指令。所以建议直接用ARM官方工具链,版本不低于10.3。

4.2.3 执行编译

OP-TEE的编译脚本在 build 目录下。进入目录,直接make:

cd ~/optee/build
make -j$(nproc) toolchains
make -j$(nproc) all

第一次编译会比较慢,大概10-20分钟。编译完成后,你会看到 out 目录下生成了这些文件:

  • flash.bin — 完整的启动镜像,包含ATF、OP-TEE、U-Boot
  • Image — Linux内核镜像
  • rootfs.cpio.gz — 根文件系统
  • tee-pager_v2.bin — OP-TEE分页二进制

4.2.4 启动QEMU验证

编译完成后,直接用脚本启动QEMU:

cd ~/optee/build
make run-only

如果一切正常,你会看到QEMU启动,Linux内核开始打印启动信息,最后进入OP-TEE的测试环境。输入 xtest 可以运行所有测试用例。

验证要点:看到 OP-TEE: initialized 这行日志,说明OP-TEE内核已经成功加载。如果卡在 Waiting for secure monitor,通常是ATF或OP-TEE的配置有问题。

4.3 开发板环境准备

模拟器跑通了,接下来就是真机。开发板的选择很多,我以最常用的 Raspberry Pi 3/4 和 QEMU vexpress-a15 为例来讲。

为什么选树莓派?便宜、文档多、社区活跃。我团队里新来的同事,我都是让他们先在树莓派上练手。

4.3.1 硬件准备清单

硬件 推荐型号 备注
开发板 Raspberry Pi 3B+ / 4B Pi 3是ARMv8 64位,Pi 4性能更好
TF卡 16GB以上,Class 10 用于烧写系统镜像
串口线 USB转TTL (3.3V) 用于查看启动日志,调试必备
电源 5V/2.5A (Pi 3) 或 5V/3A (Pi 4) 供电不足会导致随机死机

重要提醒:串口线一定要买3.3V电平的,5V的会烧坏树莓派的GPIO。我刚开始做开发时就不小心烧了一块板子,血的教训。

4.3.2 烧写系统镜像

OP-TEE官方提供了树莓派的预编译镜像。你也可以自己编译,但第一次建议先用官方镜像验证硬件是否正常。

# 下载树莓派OP-TEE镜像
wget https://github.com/OP-TEE/optee_os/releases/download/3.20.0/optee_os_rpi3_3.20.0.img.gz
gunzip optee_os_rpi3_3.20.0.img.gz

# 烧写到TF卡(假设TF卡设备是 /dev/sdb)
sudo dd if=optee_os_rpi3_3.20.0.img of=/dev/sdb bs=4M status=progress
sync

烧写完成后,把TF卡插入树莓派,连接串口线(TX接GPIO14、RX接GPIO15、GND接GND),上电启动。

4.3.3 验证开发板启动

用串口工具(如minicom或screen)连接:

sudo screen /dev/ttyUSB0 115200

正常启动后,你会看到类似下面的日志:

U-Boot 2023.01 (Jan 15 2023 - 10:30:00 +0800)
DRAM:  1 GiB
MMC:   mmc@7e202000: 0
Loading: tee.bin
OP-TEE: Revision 3.20.0 (a1b2c3d4)
OP-TEE: Initialized
Starting kernel ...

Welcome to OP-TEE on Raspberry Pi 3

看到 OP-TEE: Initialized 就说明环境搭建成功了。

4.3.4 开发板调试技巧

真机调试和模拟器不太一样。我分享几个经验:

  • 串口是命根子:没有串口日志,你根本不知道系统卡在哪。所以串口线一定要焊牢。
  • TF卡多备几张:不同版本的镜像烧在不同的卡上,切换方便。我手边常备4张卡,分别对应不同OP-TEE版本。
  • 网络启动更高效:如果开发板支持TFTP/NFS,建议配好网络启动。这样每次编译完直接通过网络加载镜像,不用反复插拔TF卡。

网络启动配置要点:在U-Boot中设置 serverip 和 ipaddr,然后用 tftp 命令加载内核和设备树。我团队现在都用这种方式,编译完一键重启,效率提升至少3倍。

4.4 环境验证清单

最后,给你一个自检清单。每完成一项就打勾:

  1. QEMU能启动ARM虚拟机,看到UEFI Shell
  2. OP-TEE源码编译成功,生成flash.bin
  3. QEMU中运行 xtest 全部通过
  4. 开发板串口输出正常,能看到OP-TEE初始化日志
  5. 开发板上能运行TA和CA的示例程序

这五项都过了,你的TEE开发环境就算彻底搭好了。接下来就可以安心写代码了。