STM32 XIP启动过程-RW和ZI数据搬移讲解

最近在RISC-V架构下基于某芯片实现XIP方式的flash代码启动,这部分代码对于我是可见的,联想到之前一直很困惑STM32的引导程序在哪里实现得将RW复制到RAM中,并RAM中初始化ZI的,写下自己的分享。以下仅针对stm32XIP模式,也就是flash启动进行讲解

引导程序

嵌入式上电后需要对需要对系统硬件和软件运行环境进行初始化,这些工作往往是由汇编语音编写的引导程序完成。引导程序是嵌入式系统上电后运行的第一段软件代码,对于嵌入式系统来说,引导程序非常关键。引导程序执行的操作依赖于开发的嵌入式系统的软硬件特性,一般的流程包括:初始化硬件、设置异常和中断向量表、把程序复制到片上RAM、完成代码重映射等,最后跳转到main入口函数。
对于CM3和CM4来说
主要做了以下工作:
1、初始化堆栈指针 SP=_initial_sp
2、初始化 PC 指针=Reset_Handler
3、初始化中断向量表
4、配置系统时钟
5、调用 C 库函数_main 初始化用户堆栈,从而最终调用 main 函数去到 C 的世界

XIP模式下RW和ZI动作

在这里插入图片描述
首先代码分为加载域和执行域,我们(烧录)加载代码后,代码及 RW 都被保存在 ROM 区(也就是stm32的nor flash)。当程序开始运行时,内核直接从 ROM 中读取代码,并且在执行主体代码前,会先执行一段加载代码,它
把 RW 节数据从 ROM 复制到 RAM, 并且在 RAM 加入 ZI 节,ZI 节的数据都被初始化为0。加载完后 RAM 区准备完毕,正式开始执行主程序。

.s启动文件上代码如下:
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main

             LDR     R0, =SystemInit
             BLX     R0
             LDR     R0, =__main
             BX      R0
             ENDP

SystemInit()代码无非是一些寄存器初始化和配置向量表偏移,我们仍然没有看到关于RW和ZI的一段,因此我们怀疑是不是__main这个调用的C库函数除了执行对堆栈的初始化还执行了这个操作,接下来我们对某工程进行反汇编,程序中具有一段名为“__scatterload”的分散加载代码,需要注意的是,这段代码它是由 armlink 链接器自动生成的
在这里插入图片描述
这段分散加载代码包含了拷贝过程(LDM 复制指令),而 LDM 指令的操作数中包含了加载的源地址,这些地址中包含了内部 FLASH 存储的 RW-data 数据。而 “__scatterload ”的代码会被“__main”函数调用,__main 在启动文件中的“Reset_Handler”会被调用,因而,在main()函数执行前,已经完成了分散加载过程,随后进入我们熟悉的世界~~

附:我们查看map文件:
符号映像表(Image Symbol Table)中有 __scatterload 指令在flash的存储位置。

Global Symbols

Symbol Name                              Value     Ov Type        Size  Object(Section)
__Vectors_Size                           0x000001ac   Number         0  startup_stm32f429xx.o ABSOLUTE
__Vectors                                0x08000000   Data           4  startup_stm32f429xx.o(RESET)
__Vectors_End                            0x080001ac   Data           0  startup_stm32f429xx.o(RESET)
__main                                   0x080001ad   Thumb Code     8  __main.o(!!!main)
__scatterload                            0x080001b5   Thumb Code     0  __scatter.o(!!!scatter)
__scatterload_rt2                        0x080001b5   Thumb Code    44  __scatter.o(!!!scatter)
__scatterload_rt2_thumb_only             0x080001b5   Thumb Code     0  __scatter.o(!!!scatter)
__scatterload_null                       0x080001c3   Thumb Code     0  __scatter.o(!!!scatter)
__scatterload_copy                       0x080001e9   Thumb Code    26  __scatter_copy.o

在存储器映射索引中,scatter 在flash的位置。
Memory Map of the image

Image Entry point : 0x080001ad

Load Region LR_IROM1 (Base: 0x08000000, Size: 0x000011dc, Max: 0x00100000, ABSOLUTE)

Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x000011bc, Max: 0x00100000, ABSOLUTE)

Base Addr    Size         Type   Attr      Idx    E Section Name        Object

0x08000000   0x000001ac   Data   RO          470    RESET               startup_stm32f429xx.o
0x080001ac   0x00000008   Code   RO         1896  * !!!main             c_w.l(__main.o)
0x080001b4   0x00000034   Code   RO         2051    !!!scatter          c_w.l(__scatter.o)
0x080001e8   0x0000001a   Code   RO         2053    !!handler_copy      c_w.l(__scatter_copy.o)
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值