【正点原子STM32MP157 启动篇】(3) STM32MP1 二进制头部信息+Linux 系统启动过程

文章目录

  • [1 概要](#1 概要)
  • [2 STM32MP1 二进制头部信息](#2 STM32MP1 二进制头部信息)
  • [3 STM23MP1 Linux 系统启动过程](#3 STM23MP1 Linux 系统启动过程)
  • [4 总结](#4 总结)
  • [5 其余章节](#5 其余章节)

1 概要

STM32 单片机是直接将程序下载到内部 Flash 中,上电以后直接运行内部Flash 中的程序。STM32MP157 内部没有供用户使用的 Flash,系统都是存放在外部 Flash 里面的,比如 EMMC、NAND等,因此STM32MP157上电以后需要从外部Flash加载程序到内存中。而且STM32MP157支持多种启动方式,这些启动方式都是怎么运行的,这都涉及到 STM32MP1 的启动方式,本章我们就来详细讲解一下 STM32MP1 的启动过程。

本章节将会分为以下5个部分

(1) STM32MP1启动模式 + STM32MP1启动流程详解

(2) Flash设备启动要求

(3) STM32MP1二进制头部信息

(4) STM32MP1 Linux系统启动过程

2 STM32MP1 二进制头部信息

前面讲了 STM32MP1 内部的 ROM 代码会先读取 FSBL 代码,一般是 TF-A 或者 Uboot 的SPL,也可以是 A7 裸机代码。比如 TF-A 我们之间编译生成二进制 bin 文件,但是这个 bin 文件不能直接拿来用,需要在前面添加一段头部信息,这段头部信息也包含了鉴权内容。加入头部信息以后的 FSBL 代码结构如图 5.4.1 所示:

头部信息一共是 256 字节,这 256 个字节的头部信息具体含义如表 5.4.1 所示:

头部信息不需要我们自己手动添加,我们在编译 ST 官方提供的 TF-A 或者 Uboot 的时候会自动添加,因为 ST 提供了个名为"stm32image"的工具专门用于在 bin 文件前面添加头部信息。我们已经从 TF-A 源码中提取出来了 stm32image 并放到了开发板光盘中,路径为:开发板光盘→5、开发工具→2、ST 官方开发工具→stm32image→stm32image.c。在编写 A7 裸机的时候需要自己使用stm32image 工具在 bin 文件前面添加头部信息,stm32image 是在 Ubuntu 下运行的,所以需要先编译,将 stm32image.c 发送到 Ubuntu 下,然后输入如下命令编译:

c 复制代码
gcc stm32image.c -o stm32image

编译成功以后就会生成一个名为 stm32image 的可执行文件,如不 5.4.2 所示:

运行图 5.4.2 编译出来的 stm32image 工具,输入"-s"选项可以查看使用方法,如图 5.4.3所示:

图 5.4.3 可以看出,stm32image 在使用的时候需要搭配一系列的参数:

-s:指定源文件。

-d:生成的目标文件。

-l:加载地址。

-e:入口地址。

-m:主版本号。

-n:次版本号。

大家在开发板光盘里面找到正点原子出厂的 tf-a 固件,路径为:开发板光盘→8、系统镜像→2、出厂系统镜像→1、STM32CubeProg 烧录固件包→tf-a→tf-a-stm32mp157d-atk-trusted.stm32,这个就是加入了头部信息的 TF-A 可执行文件。使用 winhex 软件打开 tf-a-stm32mp157d-atk-trusted.stm32,winhex软件已经放到了开发板光盘中,路径为:开发板光盘→ 3、软件→ winhexv19.7.zip,大家自行安装即可。安装完成以后打开 winhex,然后点击:文件->打开,找到tf-a-stm32mp157d-atk-trusted.stm32 并打开,如图 5.4.4 所示:

图 5.4.4 就是 tf-a-stm32mp157d-atk-trusted.stm32 文件原始数据,其中前 256 个字节就是头部信息。这里我们根据图 5.4.4 中的内容,分析一下 tf-a 头部信息中几个比较重要的参数:

**Magic number:**起始偏移地址为 0,长度为 4 个字节,值依次为:0X53、0X54、0X4D、0X32,合起来就是 0X53544D32,这个就是表 5.4.1 中的魔术数,注意这四个字节的顺序是大端模式。

**Header Version:**起始偏移地址为 72,长度为 4 个字节,也就是图 5.4.4 中第 72~75 这 4 个字节的数据,分别为:0X00、0X00、0X01 和 0X00,此时有的朋友将这四个字节拼起来发现是0X00000100,发现并不是表 5.1.1 中的 0X00010000!这不是弄错了?肯定不是的,整个头部信息中,除了 Magic number 采用大端模式存储以外,其他都是小端模式存储,也就是低字节数据存放在底地址处,高字节数据存放在高字节处。因此 0X00、0X00、0X01 和 0X00 这四个字节的数据正确的拼出结果为 0X00010000。

**Image length:**起始偏移地址为 76,长度为 4 个字节,也就是图 76~79 这 4 个字节的数据,为:0X40、0XB0、0X03 和 0X00,按照小端模式拼起来就是 0X0003B040=241728≈236.1KB,说明此 TF-A 的 bin 镜像大小为 236.1KB。

**Image entry Point:**起始偏移地址为 80,长度为 4 个字节,也就是图 80~83 这 4 个字节的数据,为:0X00、0X60、0XFD 和 0X2F,按照小端模式拼起来就是 0X2FFD6000,说明入口地址为 0X2FFD6000。

**Load address:**起始偏移地址为 88,长度为 4 个字节,也就是图 88~91 这 4 个字节的数据,为:0X00、0X25、0XFC 和 0X2F,按照小端模式拼起来就是 0X2FFC2500,说明加载地址为0X2FFC2500,这个不正是我们前面在 5.2.2 小节中分析的 FSBL 镜像起始地址。 (即偏移了256个字节后的镜像地址,前256字节用于存放相关信息)

**Binary type:**起始偏移地址为 255,也就是最后一个字节,为 0X10,表示当前二进制文件是 TF-A。

3 STM23MP1 Linux 系统启动过程

前面已经对 STM32MP1 的启动流程做了详细的讲解,STM32MP1 是面向 Linux 领域的,因此所有的这些启动过程都是为了启动 Linux 内核。STM32MP1xil 启动 Linux 内核的流程如图5.5.1 所示:

从图 5.5.1 可以看出,STM32MP1 启动 linux 内核一共分为 5 个步骤,我们依次来看一下这五个步骤的内容:

① ROM 代码

前面说了很多次了,这是 ST 自己编写的代码,在 STM32MP1 出厂的时候就已经烧写进去的,不能被修改的。ROM 代码因为保存在 STM32 内部 ROM 里面,因此也就直接简单明了的叫做"ROM 代码"了。它是处理器上电以后首先执行的程序,ROM 代码的主要工作就是读取STM32MP1 的 BOOT 引脚电平,然后根据电平判断当前启动设备,最后从选定的启动设备里面读取 FSBL 代码,并将 FSBL 代码放到对应的 RAM 空间。 (这里的RAM空间是内部的 256KB RAM,因为DDR还没有初始化,所以不能用)

现在很多产品对设备上运行的应用都提出了安全要求,从图 5.5.1 中可以看出,STM32MP1启动Linux 内核的过程是一个链式结构:ROM Code→FSBL→SSBL→Linux kernel→rootfs,系统启动的过程中要保证整个链式结构都是安全的。ROM 代码作为第一链,首先要对 FSBL 代码进行鉴权,同样的,FSBL 以及后面的每一链都要对下一个阶段的镜像进行鉴权,直到设备系统正确启动。

② FSBL

FSBL 代码初始化时钟树、初始化外部 RAM 控制器,也就是 DDR。最终 FSBL 将 SSBL 加载到 DDR 里面并运行 SSBL 代码。

一般 FSBL 代码是 TF-A 或者 Uboot 的 SPL 代码,前面我们说了,也可以将 FSBL 换成我们自己编写的 STM32MP1 A7 内核裸机代码。

③ SSBL

由于 SSBL 代码运行在 DDR 里面,无需担心空间不够,因此 SSBL 代码的功能就可以做的很全面,比如使能 USB、网络、显示等等。这样我们就可以在 SSBL 中灵活的加载 linux 内核,比如从 Flash 设备上读取,或者通过网络下载下载等,用户使用起来也非常的友好。SSBL 一般是 Uboot,用来启动 Linux 内核。

④ Linux 内核

SSBL 部分的 Uboot 就一个使命,启动 Linux 内核,Uboot 会将 Linux 内核加载到 DDR 上并运行**(加载过程可以通过网络系统或者是其他方式,因为SSBL已经初始化了很多外设功能等)**。Linux 内核启动过程中会初始化板子上的各种外设。

⑤ Linux 用户空间

系统启动的时候会通过 init 进程切换到用户空间,在这个过程中会初始化根文件系统里面的各种框架以及服务。

4 总结

本章节介绍了STM32MP1 二进制头部信息+Linux 系统启动过程。

5 其余章节

【正点原子STM32MP157 启动篇】(1)启动模式 + 启动流程详解(含UART 启动)
【正点原子STM32MP157 启动篇】(2)Flash 设备启动要求
【正点原子STM32MP157 启动篇】(3) STM32MP1 二进制头部信息+Linux 系统启动过程

相关推荐
FoldWinCard41 分钟前
D5 Linux 网络及端口命令
linux·运维·服务器
兆龙电子单片机设计1 小时前
【STM32项目开源】STM32单片机语音分类垃圾桶-蓝牙APP
stm32·单片机·嵌入式硬件·物联网·开源·自动化·毕业设计
零涂毕业设计2 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud1232 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质2 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
SakitamaX2 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.3 小时前
Linux系统管理
linux·运维
阿龙的工作记录3 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
ye150127774553 小时前
220V转5V1A隔离芯片WT5602
单片机·嵌入式硬件·其他·硬件工程
代码村新手3 小时前
Linux的基本指令
linux·运维·服务器