3、OP-TEE开发环境搭建:QEMU模拟器环境搭建、ARM开发板环境搭建、编译OP-TEE内核与TA

说实话,搭建开发环境这件事,看着简单,但坑是真不少。我见过太多人卡在这一步,折腾几天都跑不起来。其实说白了,环境搭建就是三件事:选对工具链、配好依赖、搞清楚编译流程。今天我就把我在项目中踩过的坑、总结的经验,一次性讲清楚。

3.1 环境概览:你需要什么?

在动手之前,我们先理清思路。OP-TEE的开发环境,本质上是一个交叉编译环境。你在一台x86的Linux主机上,编译出能在ARM平台上运行的代码。嗯,这里要注意,你的主机系统我建议用Ubuntu 20.04或22.04 LTS,这是目前社区支持最好的版本。

核心组件清单:

  • 主机系统:Ubuntu 20.04/22.04 LTS (x86_64)
  • 交叉编译工具链:aarch64-linux-gnu- 或 arm-linux-gnueabihf-
  • QEMU模拟器:用于无硬件时的快速验证
  • OP-TEE源码:包括optee_os、optee_client、optee_test
  • 构建工具:repo、make、gcc、python3等

3.2 QEMU模拟器环境搭建

我个人习惯先用QEMU跑起来。为什么?因为快啊!你想想看,改一行代码,QEMU上几秒钟就能验证,ARM开发板还得烧录、重启,太浪费时间了。

3.2.1 安装依赖包

先装好基础依赖。我建议你直接复制下面这条命令,别自己一个个装,容易漏。

sudo apt-get update
sudo apt-get install -y \
    android-tools-adb \
    android-tools-fastboot \
    autoconf \
    automake \
    bc \
    bison \
    build-essential \
    ccache \
    cscope \
    curl \
    device-tree-compiler \
    expect \
    flex \
    ftp-upload \
    gdisk \
    iasl \
    libattr1-dev \
    libcap-dev \
    libfdt-dev \
    libftdi-dev \
    libglib2.0-dev \
    libgmp-dev \
    libhidapi-dev \
    libmpc-dev \
    libncurses5-dev \
    libpixman-1-dev \
    libssl-dev \
    libtool \
    libusb-1.0-0-dev \
    make \
    mtools \
    netcat \
    python3 \
    python3-cryptography \
    python3-pip \
    python3-pyelftools \
    python3-serial \
    rsync \
    unzip \
    uuid-dev \
    wget \
    xdg-utils \
    xterm \
    xz-utils \
    zlib1g-dev

我曾经有一次漏装了python3-pyelftools,结果编译OP-TEE内核时报了一个莫名其妙的符号解析错误。折腾了两个小时才发现是这个问题。所以,别偷懒,一次性装全。

3.2.2 下载OP-TEE源码

OP-TEE官方推荐用repo工具来管理源码。我个人觉得这个方式挺方便的,尤其是当你需要同时管理多个git仓库时。

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

这里有个小技巧:-j4表示用4个线程并行下载。如果你的网络带宽够,可以改成-j8甚至-j16,能快不少。但如果你用的是公司内网,建议用-j1,避免被网络管理员盯上。

3.2.3 编译并运行QEMU

下载完成后,直接编译就行。OP-TEE的构建系统已经帮你配好了所有参数。

cd ~/optee/build
make -j4

编译完成后,运行QEMU:

make run-only

你会看到两个终端窗口弹出来。一个是UEFI启动的Linux内核,另一个是OP-TEE的Secure World终端。嗯,看到这个画面,说明你的环境已经搭好了。

小提示:如果你用的是虚拟机,记得给虚拟机分配至少4GB内存和2个CPU核心。否则QEMU跑起来会非常卡,甚至直接崩溃。我在项目中就遇到过这种情况,当时还以为是代码写错了,结果发现是虚拟机配置太低。

3.3 ARM开发板环境搭建

QEMU虽然方便,但毕竟不是真机。有些硬件相关的bug,只有在真机上才能复现。我个人建议,如果你手头有树莓派3B+或Juno开发板,一定要在真机上跑一遍。

3.3.1 选择开发板

OP-TEE官方支持的开发板列表如下:

开发板 SoC ARM架构 推荐用途
Raspberry Pi 3B+ BCM2837 ARMv8-A (64位) 入门学习,性价比高
HiKey 960 Kirin 960 ARMv8-A (64位) 性能测试,功能完整
Juno r2 ARM Cortex-A72/A53 ARMv8-A (64位) 企业级开发,官方推荐
STM32MP157 STM32MP157 ARMv7-A (32位) 工业控制,资源受限

如果你刚开始学,我建议用树莓派3B+。便宜,资料多,出了问题也好排查。我曾经用树莓派3B+做过一个原型项目,从零到跑通OP-TEE,大概花了两天时间。

3.3.2 烧录系统到SD卡

以树莓派3B+为例,你需要先准备一张16GB以上的SD卡。然后下载OP-TEE为树莓派预编译的镜像。

# 下载树莓派3B+的OP-TEE镜像
wget https://github.com/OP-TEE/optee_os/raw/master/scripts/brcm/rpi3/out/bin/optee.bin

# 烧录到SD卡(假设SD卡设备是/dev/sdb)
sudo dd if=optee.bin of=/dev/sdb bs=4M status=progress
sync

警告:烧录前一定要确认SD卡的设备名!我见过有人把/dev/sda(系统盘)当成SD卡来烧录,结果整个系统都废了。建议用lsblk命令查看设备列表,确认无误后再操作。

3.3.3 连接串口并启动

树莓派3B+的串口引脚是GPIO14(TX)和GPIO15(RX)。你需要一个USB转串口模块,波特率设置为115200。

# 使用minicom连接串口
sudo minicom -D /dev/ttyUSB0 -b 115200

插上电源,你会看到启动日志。如果一切正常,最后会进入OP-TEE的Secure Shell。输入xtest命令,可以运行OP-TEE的测试套件,验证环境是否正常。

3.4 编译OP-TEE内核与TA

环境搭好了,接下来就是编译。这部分我重点讲一下OP-TEE内核(optee_os)和TA(Trusted Application)的编译流程。

3.4.1 编译OP-TEE内核

OP-TEE内核的编译,说白了就是配置好平台参数,然后make。以QEMU v8为例:

cd ~/optee/optee_os
make PLATFORM=vexpress-qemu_v8 \
     CROSS_COMPILE64=aarch64-linux-gnu- \
     O=out

这里有几个关键参数:

  • PLATFORM:指定目标平台。QEMU v8用vexpress-qemu_v8,树莓派3B+用bcm-rpi3。
  • CROSS_COMPILE64:64位交叉编译工具链的前缀。如果你编译32位版本,用CROSS_COMPILE32。
  • O=out:指定输出目录。我个人习惯把编译产物单独放一个目录,方便清理。

编译完成后,你会在out/core目录下看到tee-pager_v2.bin和tee.elf。前者是最终烧录的二进制文件,后者是带调试信息的ELF文件,用于GDB调试。

调试技巧:如果你在开发过程中遇到OP-TEE内核崩溃,可以用aarch64-linux-gnu-objdump -d tee.elf反汇编,然后对照崩溃地址找到对应的代码行。我在项目中用这个方法定位过好几个内存越界的问题。

3.4.2 编译TA(Trusted Application)

TA的编译相对简单。你只需要一个TA源码目录,以及对应的Makefile。OP-TEE官方提供了一个示例TA,位于optee_examples仓库中。

# 以hello_world TA为例
cd ~/optee/optee_examples/hello_world
make CROSS_COMPILE=aarch64-linux-gnu- \
     TA_DEV_KIT_DIR=~/optee/optee_os/out/export-user_ta \
     O=out

这里的关键是TA_DEV_KIT_DIR,它指向OP-TEE内核编译时导出的TA开发套件。这个目录里包含了TA编译所需的头文件和链接脚本。

编译完成后,你会得到一个.ta文件,比如8aaaf200-2450-11e4-abe2-0002a5d5c51b.ta。这个UUID就是TA的唯一标识符。你需要把这个文件放到目标设备的/lib/optee_armtz/目录下,然后CA(Client Application)才能加载它。

3.4.3 常见编译错误及解决

我在项目中遇到过不少编译错误,这里列几个最常见的:

错误信息 原因 解决方法
aarch64-linux-gnu-gcc: command not found 交叉编译工具链未安装 sudo apt-get install gcc-aarch64-linux-gnu
fatal error: tee_internal_api.h: No such file or directory TA_DEV_KIT_DIR路径错误 检查路径是否指向export-user_ta目录
undefined reference to 'ta_entry' TA入口函数未实现 检查TA源码中是否定义了TA_CREATE_ENTRY_POINT宏
Error: selected processor does not support 'smc' instruction 编译选项与目标架构不匹配 检查CFLAGS中是否指定了正确的-march参数

嗯,这里要特别说一下最后一个错误。我刚开始做OP-TEE开发时,就栽在这个坑里。当时我用的编译器默认是ARMv7架构,但QEMU v8需要ARMv8架构。解决办法是在Makefile中加上-march=armv8-a+crypto。

3.5 验证环境:跑一个简单的TA

环境搭好了,代码也编译了,怎么验证呢?我建议你跑一下OP-TEE自带的测试套件xtest。

# 在QEMU或开发板的终端中执行
xtest

如果所有测试用例都通过,说明你的环境完全正常。如果某个测试用例失败,别慌。先看日志,找到失败的具体位置。我曾经遇到过xtest 1001失败,原因是TA的堆栈大小设置太小。把CFG_TEE_TA_STACK_SIZE从默认的1KB改成4KB就解决了。

核心要点总结:

  • QEMU环境适合快速验证,开发板环境适合硬件相关调试
  • 编译OP-TEE内核时,PLATFORM参数必须与目标硬件匹配
  • TA编译依赖TA_DEV_KIT_DIR,这个路径指向OP-TEE内核导出的开发套件
  • 遇到编译错误时,先检查工具链版本和路径配置

好了,环境搭建这部分就讲到这里。你按照这个流程走一遍,应该能顺利跑起来。如果遇到问题,记得先看日志,日志里往往藏着答案。

OP-TEE开发环境搭建流程 主机环境 (Ubuntu 20.04/22.04) 路径A:QEMU模拟器 路径B:ARM开发板 1. 安装依赖包 (apt-get install) 2. repo init + repo sync 下载源码 3. make -j4 编译OP-TEE 4. make run-only 启动QEMU 1. 选择开发板 (RPi3/HiKey/Juno) 2. 下载镜像 + dd烧录到SD卡 3. 连接串口 (minicom 115200) 4. 上电启动,运行xtest验证 编译OP-TEE内核 + TA

可可精品资料库