散列文件

(22条消息) ARM 之十三 armlink(Keil) 分散加载机制详解 及 分散加载文件的编写_ZC·Shou的博客-CSDN博客

(22条消息) KEIL的分散加载文件_keil分散加载_aron566的博客-CSDN博客

99%开发者从未听说过的堆栈模型-电子发烧友网 (elecfans.com)

MCU: ARM启动中的分散加载 - 知乎 (zhihu.com)

(22条消息) [012] [STM32] 代码重定位与清除BSS段深入分析_stm32 bss段_柯西的彷徨的博客-CSDN博客

(22条消息) keil分散加载文件_keil mem_c.scf_zhj失落之地的博客-CSDN博客

(22条消息) stm32 KEIL软件设置程序烧写起始地址_alfredseng的博客-CSDN博客

(22条消息) 韦东山第一期学习笔记——重定位_名为cainiaocl的搬运工的博客-CSDN博客

(22条消息) STM32裸机开发(7) — 复制data段和清除BSS段(ZI段)_keil bss_Willliam_william的博客-CSDN博客

(22条消息) uboot 代码重定位(位置有关码)(存储地址,运行地址,链接地址)_uboot重定向_子非龙的博客-CSDN博客

(22条消息) bootloader学习笔记---第一篇以stm32为例_stm32bootloader例程_Embedded learner的博客-CSDN博客

MDK编译过程及文件类型全解 | 码农网 (codercto.com)

stm32专题三十六:MDK编译过程和文件类型(四)-技术天地-深圳市修德电子有限公司 (szxiude.com)

【Keil】浅学一下keil中的.sct文件 - Baiyug - 博客园 (cnblogs.com)

(23条消息) keil创建无启动文件及自定义.sct文件的工程_keil5新建工程没有启动文件_小小路边草的博客-CSDN博客

(23条消息) STM32链接脚本详解_如何寻找keil链接脚本_Dokin丶的博客-CSDN博客

【Keil】浅学一下keil中的.sct文件 - Baiyug - 博客园 (cnblogs.com)

散列文件

stm32专题三十六:MDK编译过程和文件类型(四)-技术天地-深圳市修德电子有限公司 (szxiude.com)

我们可以将flash想象成一个一个标有房间,程序执行的过程就是去将这些房间里面的东西给取出来,而程序烧录的过程就是往这些房间去放入东西,那么我们往哪个房间放入哪个东西,这就十分重要,程序烧录的过程,实际上是在烧录二进制文件,也就是将二进制文件的0101的这样数据放入指定的房间,因此我们要控制在哪个房间放入哪个东西,实际上就是要控制在二进制文件的哪一个位置写入指定的数据,而散列文件就负责做这样的事情,他告诉编译器要将哪个段放在二进制文件的哪一个位置,从而使程序被烧录的时候,将断放入指定的房间中。

LR_IROM1 0x08000000 0x01000000  {    ; load region size_region
  ER_IROM1 0x08000000 0x01000000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

实际上MDK也有提供相关文档,打开MDK5页面,点击Help选择Open Books Window

在左侧选择Arm Compiler armlink User Guide Version 6.9 (PDF) 即可打开文档

加载域与执行域

加载域实际上就是指程序烧录的地方,而执行域实际上就是指程序执行的时候,使用的一个区域,而一个加载域至少要有一个执行域,但它可以对应多个执行率,以上面的代码为例,实际上就说明了,程序有一个加载域LR_IROM1,它的加载地址为0x08000000,而最大加载的数据为0x01000000,因此我们编译生成的二进制文件不能超过该大小。执行域有两个,一个在FLASH上,这是因为芯片具有XIP技术,也就是说程序可以直接在flash上进行执行,无需再将代码搬运到RAM上执行,因此运行时需要使用的区域包括了 flash, 第2个执行域是在以基地址为0x20000000的RAM上,最大的使用空间为0x00010000,这个区域存放的就是全局变量,局部变量,堆和栈

第一个执行域ER_IROM1

.o (RESET, +First) 是指定义了一个名为“RESET”的section,并将其放置在链接脚本的第一个位置,而这个段就在启动文件中,实际上指的就是中断向量表,将中断向量表放在该区域的首位

*(InRootSSSections)”是一个链接器支持的特殊选择符号,它可以选择所有标准库里要求存储到 root 区域的节区

“.ANY(+RO))”选择剩余所有节区 RO 属性的内容都分配到执行域 ER ROM1 中,之所以是剩余所有节区,是因为“.ANY”选择语句的优先级是最低的,

第二个执行域RW_IRAM1

.ANY (+RW +ZI)就是将所有的RW 与ZI 数据段存放到该区域,因此我们占用的RAM大小实际上就是RW与ZI两种数据类型(其中堆和栈被包含在ZI中)

与MAP文件的联系

主要与Memory Map of the image相关联

  • 序号1:程序入口点0x08000131,实际就是PC指针上电时的值,这个值可以发现与!!!main 的值一样(差1应该是因为Thumb 指令集的所有指令,其最低位必须为 1),

    这里的!!!main应该就是C库的main

  • 序号2:可以发现无论是加载域还是执行域的基地址都是0x08000000,与.sct设置的一致加载域的使用空间为0x000016b4,实际上就是使用的flash大小(该工程Program Size: Code=5412 RO-data=360 RW-data=40 ZI-data=1912 正好等于Code+RO-data+RW-data的大小)

  • 序号3:查看Exec Addr 与 Load Addr,可以发现两个一样

Last updated