ARM可信固件(TF-A)移植

简介: ARM可信固件(TF-A)移植

简介

  • 对于传统的 ARM 处理而言,Linux 系统的启动流程是:内部 BootROM -> uboot -> kernel -> rootfs, 整个启动过程是一个链式结构,启动过程其实是没有安全校验的,为了保证安全,ARM 推出了 Arm Trusted Firmware 的可信固件,简称 TF-A,它是一个开源的软件
  • 加入 TF-A 固件以后,TF-A 就可以对 uboot、kernel 进行校验

源码下载

  • 传统的 Linux 开发只涉及到 uboot 和 linux kernel 两个部分
  • 现在多了个 TF-A,TF-A 会先初始化 DDR 等外设,然后再把 uboot 从 flash(NAND、NOR FLASH、SD、MMC 等)拷贝到 DDR 中
  • 如果我们直接从 TF-A 官方获取 TF-A 源码的话,这样的开发难度太大,半导体厂商都会从 TF-A 官方网站下载 TF-A 源码,然后修改适配自己的芯片,我们在实际项目开发过程中一般会直接使用半导体厂商提供的 TF-A
  • 由于我使用的开发板芯片是 ST 公司的 STM32MP157,于是从 ST 官方找到相关源码:https://my.st.com/content/my_st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32-mpu-openstlinux-distribution/stm32mp1dev.html
  • ST 资料下载是需要登录账号的,如果没有账号,必须先注册一个

  • 下载完成后,需要将其拷贝到 Ubuntu 环境下,解压缩

tar -xvf en.sources-stm32mp1-openstlinux-6.1-yocto-mickledore-mp1-v23.06.21.tar.gz

  • 解压完成后,进入解压后的目录下,下面会有两个文件夹 “images” 和 “sources”,进入 sources/arm-ostl-linux-gnueabi 目录下,其内容如下所示
FIP_artifacts                               
linux-stm32mp-6.1.28-stm32mp-r1-r0     
tf-a-stm32mp-v2.8.6-stm32mp-r1-r0
gcnano-driver-stm32mp-6.4.13-stm32mp-r1-r0  
optee-os-stm32mp-3.19.0-stm32mp-r1-r0  
u-boot-stm32mp-v2022.10-stm32mp-r1-r0

TF-A 源码打补丁

  • ST 公司为 STM32MP157 这款芯片适配的 TF-A 源码就在 “tf-a-stm32mp-v2.8.6-stm32mp-r1-r0” 目录下
文件/文件夹 描述
0001-v2.8-stm32mp-r1.patch TF-A 补丁文件
Makefile.sdk 编译 TF-A 用的 MAKEFILE
README.HOW_TO.txt ST官方 TF-A的编译文档,编译方法 看此文档即
series 存放补丁名字的文件
tf-a-stm32mp-v2.8.6-stm32mp-r1-r0.tar.xz TF-A 的源码压缩包
  • ST 也是从 TF-A 官方得到的源码,然后加入自己 STM32MP157 芯片,所以 ST 也需要对 TF-A 源码进行修改,修改的方式就是打补丁,补丁文件后缀为 .patch
  • 先解压 TF-A 的源码压缩包

tar -vxf tf-a-stm32mp-v2.8.6-stm32mp-r1-r0.tar.xz

  • 接下来就是给 TF-A 源码打补丁了,进入解压好的 TF-A 源码目录下

cd tf-a-stm32mp-v2.8.6-stm32mp-r1/

  • 执行打补丁命令,其含义是把上一层目录下得所有 *.patch 后缀的文件都通过 patch 命令打补丁到当前(TF-A 源码)目录下

for p in `ls -1 ../*.patch`; do patch -p1 < $p; done

依赖工具安装

  • 上面我们得到的 TF-A 源码是 ST 提供的,这个肯定是无法在我们的开发板上运行的,需要移植和修改
  • 在正式的移植工作之前,我们可以先使用正点原子修改好的 TF-A 体验一下编译、烧录以及运行的整个过程
  • 在编译 TF-A 之前,还有一些依赖工具需要安装
  • 一个是 stm32wrapper4dbg 工具,下载地址:https://github.com/STMicroelectronics/stm32wrapper4dbg
  • 可以直接 git 拉取代码,也可以下载 zip 压缩包,如果下载的是 zip 压缩包,可以使用如下命令进行解压

unzip stm32wrapper4dbg-master.zip

  • 进入到源码目录下,执行 “make” 命令,执行完成后就会得到一个名为 “stm32wrapper4dbg” 的文件,这个就是我们要的工具,使用如下命令将其拷贝到 /usr/bin/ 目录下,这样子我们就可以在任何路径下使用这个工具了
sudo cp stm32wrapper4dbg /usr/bin/
  • 可以使用 “stm32wrapper4dbg -s” 命令测试一下是否安装成功,如果安装成功,会输出如下信息
stm32wrapper4dbg: option requires an argument -- 's'
Usage: stm32wrapper4dbg -s srcfile -d destfile [-b] [-f]
  Add a debug wrapper to a stm32 image.
  If "-b" is not specified, the wrapper would be placed
  after the last byte of the image.
Options:
  -s srcfile   input image in stm32 file format
  -d destfile  output image in stm32 file format
  -b           place the wrapper before the image
  -f           force re-adding the wrapper
  • 在编译 TF-A 之前,还有一个依赖库需要安装,是关于设备树编译相关的,输入如下命令

sudo apt-get install device-tree-compiler

编译正点原子提供的 TF-A

  • 源码位置:程序源码/1、正点原子 Linux出厂系统源码/tf-a-stm32mp-2.2.r1-gaa9f87c-v1.5.tar.bz2
  • 将其拷贝到 Ubuntu 环境下,使用如下命令解压缩
tar -xvf tf-a-stm32mp-2.2.r1-gaa9f87c-v1.5.tar.bz2
  • 首先我们要将 Makefile.sdk 中的交叉编译工具链改为我们自己开发环境中的
# CROSS_COMPILE=arm-ostl-linux-gnueabi-
CROSS_COMPILE=arm-none-linux-gnueabihf-
  • 编译 TF-A
cd tf-a-stm32mp-2.2.r1/           # 进入到 TF-A 源码目录下
make -f ../Makefile.sdk all       # 编译 TF-A,-f:指定 Makefile
  • 编译完成后,如果出现如下提示,则说明编译成功
Built /home/thin-wind/atk/tf-a-stm32mp-2.2.r1/../build/serialboot/tf-a-stm32mp157d-atk.bin successfully
Generate /home/thin-wind/atk/tf-a-stm32mp-2.2.r1/../build/serialboot/tf-a-stm32mp157d-atk.stm32
Image Type   : ST Microelectronics STM32 V1.0
Image Size   : 241728 bytes
Image Load   : 0x2ffc2500
Entry Point  : 0x2ffd6000
Checksum     : 0x00e24c6a
Option     : 0x00000001
Version    : 0x00000000
Building stm32mp1
make[1]: Leaving directory '/home/thin-wind/atk/tf-a-stm32mp-2.2.r1'
Image Type   : ST Microelectronics STM32 V1.0
Image Size   : 241784 bytes
Image Load   : 0x2ffc2500
Entry Point  : 0x2fffd541
Checksum     : 0x00e26305
Option       : 0x00000001
Version      : 0x00000000
Halt Address : 0x2ffd6000
  • 编译完成后会在上一层目录下生成 "build" 目录,进入 build/trusted/ 目录,如下红框标记的即为正点原子开发板使用的 tf-a-stm32mp157d-atk-trusted.stm32

准备烧录文件

  • 在烧录前,我们要提前准备好如下文件
atk_emmc-stm32mp157d-atk-qt.tsv
tf-a-stm32mp157d-atk-serialboot.stm32
tf-a-stm32mp157d-atk-trusted.stm32
u-boot.stm32
  • 其中,只有 tf-a-stm32mp157d-atk-trusted.stm32 这个文件是我们编译生成的
  • tf-a-stm32mp157d-atk-serialboot.stm32: 由原子提供,路径:8、系统镜像/2、出厂系统镜像/1、 STM32CubeProg烧录固件包/tf-a/tf-a-stm32mp157d-atk-serialboot.stm32
  • u-boot.stm32: 由原子提供,路径:8、系统镜像/2、出厂系统镜像/1、 STM32CubeProg烧录固件包/uboot/u-boot.stm32
  • atk_emmc-stm32mp157d-atk-qt.tsv: 由原子提供,路径:8、系统镜像/2、出厂系统镜像/1、 STM32CubeProg烧录固件包/flashlayout/atk_emmc-stm32mp157d-atk-qt.tsv
  • 为什么需要 tf-a-stm32mp157d-atk-serialboot.stm32 和 u-boot.stm32 这两个文件?tf-a-stm32mp157d-atk-serialboot.stm32 用来初始化 USB、DDR 等外设, DDR初始化了以后就可以运行 uboot 了,为什么要运行 uboot 呢?因为 uboot里面会初始化 EMMC、NAND 等外设,而且 uboot 会提供很强大的 EMMC 操作指令。也就是说,启动 uboot的目的就是为了操作 EMMC、 NAND,这样就可以在 uboot 里面通过相关的命令将 tf-a-stm32mp157d-atk-trusted.stm32 写到 EMMC 或者 NAND 里面
  • *.tsv 文件是 STM32CubeProgrammer 的烧录脚本配置文件,是文本格式的,很容易阅读,关于 .tsv语法的详细讲解,请参考 https://wiki.st.com/stm32mpu/wiki/STM32CubeProgrammer_flashlayout
  • 将 atk_emmc-stm32mp157d-atk-qt.tsv 文件修改成下面的样子,注意不能使用空格,必须使用 Tab 键
#Opt  Id  Name  Type  Device  Offset  Binary
-  0x01 fsbl1-boot  Binary  none  0x0  tf-a-stm32mp157d-atk-serialboot.stm32
-  0x03 ssbl-boot Binary  none  0x0  u-boot.stm32
P  0x04 fsbl1  Binary mmc1  boot1 tf-a-stm32mp157d-atk-trusted.stm32
P  0x05 fsbl2  Binary mmc1  boot2 tf-a-stm32mp157d-atk-trusted.stm32
  • 关于 *.tsv 内容暂时就不做具体说明了,研究明白了也不一定用的到,不同的芯片烧录方式也是不一样的,我建议是除非工作中用到,否则没必要过度研究工具的使用

烧录 TF-A

  • 烧录工具:STM32CubeProgrammer, 下载地址:https://www.st.com/zh/development-tools/stm32cubeprog.html#get-software
  • 一切准备就绪,下面就是实际烧录环节了
  • 首先设置开发板拨码开关为000,也就是从 USB 启动
  • 按下图连接硬件 USB

  • 连接成功后,通过设备管理器查看相关驱动是否 OK,安装完成 STM32CubeProgrammer 后可能找不到 DFU,重启电脑即可

  • 打开 STM32CubeProgrammer 软件,按如下步骤连接 USB

  • 连接成功后显示如下,点击 “Open file”

  • 选择刚刚准备好的烧录文件中的 *.tsv 文件,按如下操作

  • 烧录成功后会有如下提示:

TF-A 的运行

  • 烧录成功后,接下来就是要测试一下能否运行
  • 断电,设置开发板拨码开关为010,也就是从 EMMC 启动
  • 打开串口工具,波特率设置为 115200
  • 上电,TF-A 是最先启动的,从打印输出的时间可以看出我们编译的 TF-A 已经成功运行了

TF-A 启动顺序

  • TF-A 一共分为 5 部分:bl1、bl2、bl31、bl32、bl33,打开 TF-A 源码,可以看到 bl1、bl2、bl31、bl32 这 4 个文件夹,并没有 bl33,这是因为 bl33 是 TF-A 启动的其它第三方镜像固件,比如 uboot
  • TF-A 的启动流程:bl1 -> bl2 -> (bl31/bl32/bl33), bl31、bl32 和 bl33 对应的镜像不需要全部都有,但 bl33 一般是必须的,因为 bl33 一般是 uboot
目录
相关文章
|
7月前
|
JSON Ubuntu Linux
LuaJit交叉编译移植到ARM Linux
LuaJit交叉编译移植到ARM Linux
149 1
|
7月前
|
Linux 计算机视觉
Linux交叉编译opencv并移植ARM端
通过以上步骤,你可以在Linux上交叉编译OpenCV,并将生成的库文件和头文件移植到ARM平台上,从而在ARM上使用OpenCV。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
477 0
STM32CubeIDE移植ARM DSP库
STM32CubeIDE移植ARM DSP库
|
Ubuntu 物联网 编译器
手把手移植物联网项目到arm开发板笔记(下)
手把手移植物联网项目到arm开发板笔记(下)
244 0
|
Ubuntu 物联网 Linux
手把手移植物联网项目到arm开发板笔记(上)
手把手移植物联网项目到arm开发板笔记
423 0
|
NoSQL Ubuntu Linux
arm嵌入式gdb移植和搭建远程gdb调试运行环境
arm嵌入式gdb移植和搭建远程gdb调试运行环境
813 0
arm嵌入式gdb移植和搭建远程gdb调试运行环境
|
Linux 编译器 Shell
arm嵌入式Linux系统移植实例过程及问题
arm嵌入式Linux系统移植实例过程及问题
515 0
|
Linux 编译器 网络安全
嵌入式Linux开发: 移植curl到arm平台(Tiny4412)
嵌入式Linux开发: 移植curl到arm平台(Tiny4412)
890 0
嵌入式Linux开发: 移植curl到arm平台(Tiny4412)
|
安全 编译器 Linux
QT5.6移植到ARM三星4412-
QT5.6移植到ARM三星4412-
236 0
QT5.6移植到ARM三星4412-
|
API 开发者 Windows
开发者逆向工程将《星际争霸》移植到ARM平台
醒来吧,我的孩子们。拥抱你们与生俱来的荣耀。你们须知,我是你们的主宰,虫族永恒的意志。你们生来就是为我服务的。
289 0
开发者逆向工程将《星际争霸》移植到ARM平台