1 系统源码
- ST 官方 TF-A、uboot、kernel 等源码下载链接为:
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
u-boot-stm32mp-2020.01-r0、linux-stm32mp-5.4.31-r0和tf-a-stm32mp-2.2.r1-r0。也就是 TF-A、Uboot 和 Linux Kernel。传统的 linux学习中不需要 TF-A 的,只需要 uboot 和 Linux Kernel,但是 MP1 带有安全硬件,因此加入了TF-A。
2 STM23MP1 Linux系统启动过程
- STM32MP1 启动 linux 内核一共分为 5 个步骤,我们依次来看一下这五个步骤的内容:
2.1 ROM代码(ROM Code→FSBL→SSBL→Linux kernel→rootfs)
- 这是 ST自己编写的代码,在STM32MP1 出厂的时候就已经烧写进去的,不能被修改的。它是处理器上电以后首先执行的程序,
ROM 代码的主要工作就是读取STM32MP1的BOOT引脚电平,然后根据电平判断当前启动设备,最后从选定的启动设备里面读取FSBL代码,并将FSBL代码放到对应的RAM 空间。 - 启动 Linux 内核的过程是一个链式结构:ROM Code→FSBL→SSBL→Linux kernel→rootfs,系统启动的过程中要保证整个链式结构都是安全的。ROM 代码作为第一链,首先要对 FSBL 代码进行鉴权,同样的,FSBL 以及后面的每一链都要对下一个阶段的镜像进行鉴权,直到设备系统正确启动。
2.2 FSBL
- FSBL 代码初始化时钟树、初始化外部 RAM 控制器,也就是 DDR。最终 FSBL 将 SSBL 加载到 DDR 里面并运行 SSBL 代码。
一般 FSBL 代码是 TF-A 或者 Uboot 的 SPL 代码
2.3 SSBL
- 由于 SSBL 代码运行在 DDR 里面,无需担心空间不够,因此 SSBL 代码的功能就可以做的很全面,比如使能 USB、网络、显示等等。这样我们就可以在 SSBL中灵活的加载 linux 内核,比如从 Flash 设备上读取,或者通过网络下载下载等,用户使用起来也非常的友好。SSBL一般是Uboot,用来启动 Linux 内核。
2.4 Linux内核
- SSBL部分的Uboot 就一个使命,启动 Linux 内核,Uboot 会将 Linux 内核加载到DDR上并运行。Linux 内核启动过程中会初始化板子上的各种外设。
2.5 Linux用户空间
- 系统启动的时候会通过 init 进程切换到用户空间,在这个过程中会初始化根文件系统里面的各种框架以及服务。
3 TF-A概述
- TF-A 是 ARM 可信任固件,是ARM 官方提供的一个固件代码,它提供了统一的接口标准,方便不同的半导体厂商将自家的芯片添加到 TF-A 里面。F-A 官网地址为:www.trustedfirmware.org/,此网站不仅仅提供了 TF-A,还有针对Cortex-M 单片机的 TF-M,以及 OP-TEE 等安全相关软件库。
- TF-A 一共分为 5 部分:bl1、bl2、bl2u、bl31、bl32 和 bl33,打开 TF-A 源码目录,可以看到这 5 部分,如图所示:
- bl1、bl2、bl31、bl32 和 bl33 是 TF-A 的不同启动阶段,TF-A 的启动过程是链式的,不同的阶段完整的功能不同, bl1、bl2、bl31、bl32 和 bl33 全名如下:
- STM32MP1 的 TF-A 启动流程
- TF-A 启动分了 5 步,这 5 步的含义如下::
4 烧录
4.1 从EMMC启动
- ST 会使用 EMMC 的 boot1 和 boot2 这两个分区作为 FSBL,但是同一时间只有一个有效,ROM代码会加载有效的哪个 FSBL。ROM
4.2 从SD卡启动
- SD卡也包含两个 FSBL,但是SD卡没有boot1和boot2 这样的物理分区。ROM 代码默认尝试加载第一个 FSBL,如果第一个 FSBL 加载失败,那么 ROM 代码就会加载第二个 FSBL。
4.2 烧录(准备FlashLayout)
- tf-a-stm32mp157d-atk-serialboot.stm32 中间有个“serialboot”,也就是串行 BOOT,
说明是和启动有关的,此固件用来初始化 USB、DDR 等外设 - DDR 初始化了以后就可以运行 uboot 了,为什么要运行 uboot 呢?因为 uboot 里面会初始化 EMMC、NAND 等外设,而且 uboot 会提供很强大的 EMMC 操作指令。也就是说,
启动 uboot 的目的就是为了操作 EMMC、NAND,这样就可以在 uboot 里面通过相关的命令将 tf-a-stm32mp157d-atk-trusted.stm32 写到 EMMC 或者NAND 里面。这就是需要 tf-a-stm32mp157d-atk-serialboot.stm32 和 u-boot.stm32 的原因,这两个文件存在的目的就是为了将 tf-a-stm32mp157d-atk-trusted.stm32 烧写到 EMMC、NAND、SD 卡里面。 - 设置开发板拨码开关为 为 010 ,也就是从 EMMC 启动