96SEO 2026-02-23 11:37 6
Flash加载程序到内存中。

而且STM32MP157支持多种启动方式这些启动方式都是怎么运行的这都涉及到
如上图中所示CA7是Cortex-A7的缩写可看出A7啮合有128KB的ROM空间起始地址为0X00000000STM32MP1上电后会先运行这段
内部ROM代码肯定会有个默认的引脚比如内部默认使用PB14如果你自己绘制的板子用了
那么就会出问题。
当然了可以通过修改OTP来设置启动设备所使用的引脚但是OTP只能改一次如果改错了开发板就废了所以如果自制开发板启动设备的引脚一定要和ST官方一致比较方便
STM32MP157开发板上通过拨码开关来选择启动模式开发板上有丝印提示如何选择不同的启动方式如下图所示
STLINK访问A7或者M4内核一般是通过此方法来调试M4内核代码Secondary
boot(第二个内核启动)复位以后STM32MP157的每个A7内核都会启动并且运行相同的指令。
内部ROM代码会分离执行流只有Core0才会运行ROM代码另外一个内核会处于一个死循环状态等待应用程序发送信号来进行下一步操作。
这个信号是由SGI(软中断)和另外两个BACKUP寄存器
BRANCH_ADDRESS组成。
如果要启动Core1运行在Core0的应用程序需要将跳转地址写入
MAGIC_NUMBER寄存器向Core1和发送SGI中断也就是说只要不手动开启第二个核那么由于内部
ROM代码的作用此时STM32MP157就相当于单核A7。
这样有利于我们编写的STM32MP157的A7裸机例程因为只需要考虑单核情况RMA
Authorization的缩写正点原子的教程中并没有涉及这种启动方式低功耗唤醒提供安全相关服务。
这张图中红色的区域就是最常用的启动方法所以我们需要重点关注这一部分就是上电/复位后的运行流程
首先检查当前是不是CPU0运行如果不是就启动CPU1正常上电肯定是CPU0如果是CPU0检查复位原因检查是否为退出Standby导致的复位如果不是进入RMA检查检查是否为RMA启动不是检查是否为ENGI启动检查是否为ENGI启动不是就直接进冷启动进入冷启动后就从FLASH中加载系统并进行鉴权如果鉴权成功就运行系统。
FSBL镜像就是ROM加载的第一个用户编写的可执行程序一般是TF-A镜像但是我们可以换成自己编写的程序比如A7裸机代码。
这个FSBL镜像是有要求的不是简单的把bin文件丢过来就可以而是需要在bin文件前面添加一个头部信息FSBL镜像加载后需要对其进行鉴权如果鉴权成功那么就会跳转到FSBL镜像入口地址开始运行FSBL固件。
FSBL镜像文件并运行但是此时DDR还没有初始化FSBL镜像要存放在内部RAMST32MP1内部有
256KB。
ROM代码会将FSBL镜像拷贝到0X2FFC2400地址但是要注意FSBL镜像的起始地址不是0X2FFC2400因为FSBL镜像前面还有一个
FSBL镜像的真正起始地址为0X2FFC24000X1000X2FFC2500。
搞清楚这个起始地址是为了方便在之后将FSBL镜像换成A7裸机例程编译的时候要指定链接起始地址这个链接起始地址就是
0X2FFC2500由此可以计算出整个FSBL镜像大小不能超过
0X30000000-0X2FFC2500252672B246.75KB。
ROM代码会boot上下文的起始地址保存到R0寄存器然后跳转到
FSBL镜像的入口地址这个入口地址会定义到头部里面其实就是上面讲的
boot上下文会保存到SYSRAM的前512字节里面boot上下文包含了boot信息比如选定的
boot设备还有一些和安全启动鉴权有关的服务。
结构体boot_api_context_t定义了
boot上下文结构boot_api_context_t结构体是定义在
TF-A源码里面的(plat/st/stm32mp1/include/boot_api.h)内容如下所示
BOOT_API_CTX_BOOT_INTERFACE_SEL_XXX
BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY*
BOOT_API_CTX_STBY_EXIT_STATUS_XXX*
BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY
BOOT_API_CTX_CSTBY_EXIT_STATUS_XXX*
(*bootrom_ecdsa_check_key)(uint8_t
(*bootrom_ecdsa_verify_signature)(uint8_t
(*bootrom_ecdsa_verify_and_go)(uint8_t
sd_err_internal_timeout_cnt;uint32_t
emmc_nbbytes_rxcopied_tosysram_download_area;uint32_t
boot_api_ssp_config_t*/boot_api_ssp_config_t
BOOT_API_CTX_SSP_STATUS_XXX*/uint32_t
boot_api_context_t;boot_api_context_t结构体目前不需要去研究后面学习
当我们设置BOOT2~BOOT0为串行启动也就是从USB或UART启动的时候就会进入此模式。
当选择串行启动以后ROM代码就会并行扫描所有可以启动的UART以及USB
8,10,12,14,16,20,24,25,26,28,32,36,40,48
正点原子STM32MP157开发板使用24M有源晶振作为HSE时钟源。
可通过设置OTP来更改ROM代码的HSE晶振大小设置如下图所示
24MHz虽然可以通过修改OTP来更改HSE但是强烈不建议因为OTP只能修改一次一旦修改错误芯片就废了
如果要选择UART启动也就是通过UART烧写系统那么只能使用USART2、USART3、UART4、UART5、USART6、UART7或UART8此时串口工作模式为1位起始位、8位数据位、偶校验、1位停止位、波特率115200。
IO可以使用比如UART4的RX(接收)可以使用PI10、PH14、PA1、PA11、PB2、PB8、PC11
PD0或PD2一共9个IO可以用作UART4_RX引脚但是ROM代码里面的UART4_RX引脚肯定只会使用这个9个里面的其中一个所以我们板子的串口引脚要和ROM代码里面的一致否则就无法使用串口启动。
ROM代码里面串口使用的引脚如下图所示
如果要使用串口启动那么相关串口IO一定要参考上图中定义的IO引脚比如正点原子开发板UART4的RX引脚使用PB2TX引脚使用PG11。
Flash设备启动但是不同的Flash设备在启动的时候有不同的要求。
linux系统自身编译出来就是一个镜像文件但是这个镜像文件要运行是需要一大堆的“小弟”来辅助。
比如需要uboot来启动启动以后还需要根文件系统
rootfs但是对于STM32MP1而言又多了几个需求比如TF-A、TEE、vendorfs等所有这一大堆构成了
最终的系统镜像。
系统镜像是要烧写到Flash设备中的这些不同的文件肯定要按照一定的要求分门别类的烧写并存放到指定位置。
针对Flash设备可以通过创建不同的分区来存放不同的文件ST针对STM32MP1系列给出了官方分区建议这些建议包含了Flash分区数量、分区最小空间、分区存放的内容等如下图所示
NAND前几个块(block)里面包含了多份FSBLROM代码会从第一个块开始扫描并且加载第一个有效块里面的FSBL。
ROM代码支持并行NAND和串行NAND并行NAND连接到FMC总线上串行NAND连接到QSPI上。
EMMC在物理结构上有boot1、boot2、RPMB(Replay
一般常用的就是UDA分区也就是用户数据区域很少会关心boot1、boot2这样的分区。
boot1、
存在的意义就是用于引导系统。
正点原子STM32MP157开发板所使用的EMMC型号为KLM8G1GETF这是三星的一颗8GB
从图中可以看出对于三星的8GB的EMMC而言boot1和boot2分区默认大小为4096KBRPMB
ST会使用EMMC的boot1和boot2这两个分区作为FSBL但是同一时间只有一个有效ROM代码会加载有效的那个FSBL。
ROM代码使用单bit模式来操作EMMC默认情况下ROM代码使用连接到SDMMC2上的EMMC可以通过OTP来修改EMMC所使用的SDMMC接口但是这里不建议OTP只能更改一次
SD卡也包含两个FSBL但是SD卡没有boot1和boot2这样的物理分区。
ROM代码默认尝试加载第一个FSBL如果第一个FSBL加载失败那么ROM代码就会加载第二个FSBL。
ROM代码首先在SD卡上查找GPT分区如果找到的话就查找名字以“fsbl”开始的两个FSBL分区。
如果没有找到GPT分区的话就直接根据物理地址查找两个FSBL第一个FSBL的起始偏移地址为LBA34地址为34512174080X4400所以第一个FSBL的起始地址为0X4400。
第二个FSBL的起始偏移地址为LBA546地址为5465122795520X44400所以第二个FSBL的起始地址为0X44400。
ROM代码默认也是使用单bit模式操作SD卡并且默认使用连接到SDMMC1接口上的
之前的内容就是讲了ROM代码会先读取FSBL代码一般是TF-A或者Uboot的SPL也可以是A7
裸机代码。
比如TF-A我们直接编译生成二进制bin文件但是这个bin文件不能直接拿来用需要在前面添加一段头部信息这段头部信息也包含了鉴权内容。
加入头部信息以后的FSBL代码结构如下图所示
头部信息不需要手动添加在编译ST官方提供的TF-A或者Uboot的时候会自动添加因为ST提供了个名为“stm32image”的工具专门用于在bin文件前面添加头部信息。
这个工具就是一个stm32image.c文件在正点原子的开源资料中是有的可以直接获取在编写A7裸机的时候需要自己使用stm32image工具在bin文件前面添加头部信息
stm32image是在Ubuntu下运行的所以需要先编译将stm32image.c发送到Ubuntu下然后输入如下命令编译
编译成功以后就会生成一个名为stm32image的可执行文件如下图所示
“-s”选项可以查看使用方法stm32image在使用中需要搭配一系列参数
在正点原子的开发板光盘里面找到正点原子出厂的tf-a固件里面的tf-a-stm32mp157d-atk-trusted.stm32就是加入了头部信息的
tf-a-stm32mp157d-atk-trusted.stm32如下图所示
上图tf-a-stm32mp157d-atk-trusted.stm32文件原始数据其中前
256个字节就是头部信息。
可以分析一下tf-a头部信息中几个比较重要的参数
number起始偏移地址为0长度为4个字节值依次为0X53、0X54、0X4D、0X32合起来就是0X53544D32这个就是魔术数
注意这四个字节的顺序是大端模式即高字节数据存放在底地址处低字节数据存放在高字节处Header
0X00、0X00、0X01和0X00整个头部信息中除了Magic
number采用大端模式存储以外其他都是小端模式存储也就是低字节数据存放在底地址处高字节数据存放在高字节处。
因此0X00、0X00、0X01和0X00这四个字节的拼出结果为
length起始偏移地址为76长度为4个字节也就是上图76~79这4个字节的数据为0X40、0XB0、0X03和0X00按照小端模式拼起来就是0X0003B040241728约为236.1KB说明此TF-A的
Point起始偏移地址为80长度为4个字节也就是图80~83这4个字节的数据为0X00、0X60、0XFD和0X2F按照小端模式拼起来就是0X2FFD6000说明入口地址为
address起始偏移地址为88长度为4个字节也就是上图88~91这4个字节的数据为0X00、0X25、0XFC和0X2F按照小端模式拼起来就是0X2FFC2500说明加载地址为0X2FFC2500就是FSBL镜像起始地址Binary
type起始偏移地址为255也就是最后一个字节为0X10表示当前二进制文件是TF-A。
STM32MP1是面向Linux领域的因此以上所有启动过程都是为了启动Linux内核。
从上图中可以看出STM32MP1启动linux内核一共分为5个步骤
这是ST自己编写的代码在STM32MP1出厂的时候就已经烧写进去的不能被修改的。
ROM
代码因为保存在STM32内部ROM里面因此也就直接简单明了的叫做“ROM
代码”了。
它是处理器上电以后首先执行的程序ROM代码的主要工作就是读取STM32MP1的BOOT引脚电平然后根据电平判断当前启动设备最后从选定的启动设备里面读取FSBL代码并将FSBL代码放到对应的RAM空间。
为了安全性的要求从上图中可以看出。
STM32MP1启动Linux内核的过程是一个链式结构ROM
kernel→rootfs系统启动的过程中要保证整个链式结构都是安全的。
ROM代码作为第一链首先要对FSBL代码进行鉴权同样的FSBL以及后面的每一链都要对下一个阶段的镜像进行鉴权直到设备系统正确启动。
FSBL代码初始化时钟树、初始化外部RAM控制器也就是DDR。
最终FSBL将SSBL加载到DDR里面并运SSBL代码。
一般FSBL代码是TF-A或者Uboot的SPL代码当然也可以换成A7内核裸机代码。
由于SSBL代码运行在DDR里面无需担心空间不够因此SSBL代码的功能就可以做的很全面比如使能USB、网络、显示等等。
这样我们就可以在SSBL中灵活的加载
linux内核比如从Flash设备上读取或者通过网络下载下载等用户使用起来也非常的友好。
SSBL一般是Uboot用来启动Linux内核。
SSBL部分的Uboot就一个使命启动Linux内核Uboot会将Linux内核加载到DDR上并运行。
系统启动的时候会通过init进程切换到用户空间在这个过程中会初始化根文件系统里面的各种框架以及服务。
这一章的主要内容就是大概介绍了一下STM32MP1系列的启动过程介绍了STM32MP1的启动模式是通过3个BOOT引脚的切换进行选择启动通过ROM代码运行FSBL代码一般是TF-A代码也可以是A7裸机代码主要的内容就是启动的部分可以从USB或者UART启动也可以Flash设备启动SSBL是第二阶段的启动这其中就是启动Linux内核和用户空间。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback