1.LD链接脚本的简介
LD链接脚本的概念
- LD链接器脚本在完整程序编译流程中的链接过程使用。
- LD链接器脚本定义了程序各个程序段的存储分布,描述链接器如何将这些目标文件.o文件链接成一个输出可执行文件
- LD链接器脚本与CPU的种类、MCU的内部存储器分布有关。
LD链接器脚本的使用
- 第三方SDK例如Keil uvision:无需LD链接器脚本,只需在Options简单配置例如设置ROM区域和RAM区域在MCU内部的存储器使用地址,SDK就会自动配置程序各个段所在MCU内部存储器的位置。
- 官方SDK STM32CUBEIDE:需要LD链接器脚本,但是一般无需用户参与编辑,SDK可以自动完成脚本的维护,同时用户也可以主动编辑脚本的内容。
- linux-环境arm-gcc:需要用户手动配置LD链接脚本,这个LD链接脚本内容和上述第二种的LD链接脚本非常相似。
- 一般对于MCU硬件开发和MCU验证阶段会涉及并使用LD链接脚本。而平时使用MCU单片机完成特定的功能,属于应用阶段,一般不太会使用到LD链接脚本
以ARM Cortex M3核STM32F103系列MCU为例。
2.LD链接器脚本的功能
LD链接器脚本的功能
- 定义RAM区域和ROM区域的地址信息,包括首地址、长度。
- 定义各个程序段在MCU内部存储器中的分布情况。
- 定义复位程序的入口。
存储器地址信息的定义
- 一般情况下,RAM区域指的是可读可写区域,ROM区域指的是只读区域。
- RAM区域、ROM区域只是一个名称而已,真正要看的是他们这个地址的值。
- ROM区域一般都是FLASH存储器,RAM区域一般都是内部SRAM。
存取区域地址信息的定义
- MEMORY:对存储区域进行设置
- 定义信息包括区域的首地址ORIGIN、大小LENGTH、读写权限(xrw可读可写可执行,rx可读可执行)
- STM32F103系列,分为FLASH(属于ROM区域)和RAM区域。
存储区域地址信息的定义
- 栈段的地址空间位于RAM区域的末尾,且由高地址往低地址生长。
- estack代表栈段的首地址,其地址位RAM区域的首地址加上RAM区域的长度,即RAM区域的末地址。
- 这里的Heap_Size指的是堆的大小,Stack_Size指的是栈的大小。
各段在存储区域的排布
- 对各程序的段在存储区域的排布做了定义,包括TEXT段、RODATA段、DATA段、BSS段、堆栈段。
- SECTIONS:设置程序中的各个段放在指定的地址空间,包括TEXT段、RODATA段、DATA段、BSS段、堆栈段等。
- isr_vector段包含了是中断向量表信息,是在.S启动文件定义的。
- 堆空间和栈空间可以合并,TEXT段和RODATA段可以合并。
代码分析
- 点.代表当前地址,冒号:代表当前是哪一个程序的段。
- SECTIONS部分中每一个程序的段都按照先后顺序依次在地址空间排布。
- 大于号>代表存储在哪个区域里面。
- ALIGN(4)代表4字节对齐,点.等于ALIGN(4)代表当前地址开始4字节对齐。
- _extext=.这是一个赋值语句,把当前地址赋值给这个extext变量。
- 截图部分:isr_vector段放在FLASH区域的首地址,其内容都是4字节地址对齐,TEXT段紧接着放在isr_vector段后面,其内容也是4字节对齐,etext变量的值为TEXT段的末地址。
- >RAM AT>FLASH:该段存储于FLASH区域但是运行时加载至RAM区域。该加载操作是.S启动文件执行的。
- 每当出现一个不同区域例如FLASH区域后出现RAM区域,则从该区域的首地址重新排布。
- LOADADDR指的是加载后的地址,所以sidata指的是DATA段加载到RAM区域后的首地址。
- user_heap_statck段不是真正的堆栈地址,这个是用来检查算上堆栈的大小后RAM区域的地址空间是否溢出即超出RAM区域边界。实际上真正使用的堆栈段位于RAM区域的结尾处。
- SECTIONS内部完整含义:
isr_vector段放在FLASH区域的首地址。TEXT段紧接着放在isr_vector段后面,RODATA段紧接放在TEXT段的后面,这三个段的内容都是4字节地址对齐。
DATA段其内容也是4字节对齐,存储在FLASH区域紧接着RODATA的末尾,但是运行时被加载至的RAM区域的首地址。BSS段位于RAM区域紧接着加载后DATA段的末尾。
SECTIONS:
etext变量的值为TEXT段的末地址
sdata为DATA段的首地址
edata为DATA的末地址
sbss为BSS段存储的首地址
ebss为BSS段存储末地址
sidata为DATA段被加载到RAM区域后的首地址
复位程序入口
- ENTRY用于指定程序运行的入口,默认是Reset_Handler.