RK3399Pro 移植主线arm trusted firmware和optee

RK3399Pro 移植主线arm trusted firmware和optee


0.前言

  Rockchip发布的 rkbin 固件中,有预编译好的 BL31 和 BL32 文件,通常情况下,只需要 BL31 作为 TF-A 使用,即可正常引导 Arm v8 的启动流程。另外,官方提供的 BL32 文件是不带 OPTEE 头的,如果在 uboot 工程编译中使用这个固件,会警告固件无法识别,实际运行时也没有真正生效。既然要自己移植了,索性连着这部分一起使用主线源码进行编译。

一、准备工作

  由于 linaro 已停止发布 gcc 编译工具链,arm 官网上基本都是 aarch64-none-* 前缀的交叉编译链,通常不会链接 glibc,所以这里笔者直接通过 apt 安装的交叉编译工具链,一定程度上也提升了泛用性。

bash 复制代码
# 用于编译主体程序及后续uboot等
sudo apt install gcc-aarch64-linux-gnu

# arm trusted firmware中会用到
sudo apt install gcc-arm-none-eabi

# OPTEE中会用到
sudo apt install gcc-arm-linux-gnueabihf

其他的依赖环境请读者自行完善。

源码仓库:

bash 复制代码
# arm trusted firmware
git clone https://github.com/ARM-software/arm-trusted-firmware.git -b v2.13.0

# optee
git clone https://github.com/OP-TEE/optee_os.git

注意:RK3399 使用主线 TF-A 时,最高只支持到 v2.13.0 版本,更高版本由于一些 CVE 漏洞补丁的原因,会导致编译出的固件大小超出 RK3399 的 PMUSRAM(最大8KBit),此部分经过多种方式均未解决,只能等后续完善。

二、编译

先编译 OPTEE:

bash 复制代码
cd <path_to_optee>
make -j$(nproc) \
  PLATFORM=rockchip-rk3399 \
  CROSS_COMPILE64=aarch64-linux-gnu- \
  CROSS_COMPILE32=arm-linux-gnueabihf- \
  CFG_ARM64_core=y \
  CFG_WITH_ARM_TRUSTED_FW=y \
  CFG_TEE_CORE_LOG_LEVEL=2

此步骤会得到编译产物out/arm-plat-rockchip/core/tee.binout/arm-plat-rockchip/core/tee.elfout/arm-plat-rockchip/core/tee-pager_v2.bin,其中 tee.bin 就是后续会用到的 BL32 固件。

再编译 TF-A 固件:

bash 复制代码
cd <path_to_tf-a>
make -j$(nproc) \
  PLAT=rk3399 \
  CROSS_COMPILE=aarch64-linux-gnu- \
  SPD=opteed \
  BL32=<path_to_tee.bin> \
  DEBUG=0

这里声明了BL32的校验模式和路径,但在编译时并不会将BL32打包进编译结果,主要是为后续的 uboot 提前添加声明。DEBUG=0 是为了降低编译产物的大小,由于使用的交叉编译工具链可能版本不同,有概率还会出现之前的固件大小 overflow 的问题,这里就直接关闭了,可以自行尝试取消和调试。

编译产物为build/rk3399/release/bl31/bl31.elf

到这里,移植主线uboot和kernel需要的前置文件基本上准备完毕。有关 Arm v8 架构的上电启动步骤和校验流程,这里暂时不做赘述,有兴趣的读者可以站内查找。