嵌入式软件开发在源码project中打开文件视图树,会发现除了源码文件、makefile外,往往还有两类文件:链接文件(如.ld、.lds等)和crt*.s(常见的是crt0.s,在arch目录下)。
1 链接文件
1.1 基础知识
链接过程就是将源代码编译后的多个目标文件(.o,.obj)合并成一个二进制文件(*.elf)的过程,这个文件一般都会包括text、data和bss等section:
- text:代码段,就是cpu要执行的指令
- data:数据段,程序中使用的数据变量,全局变量、静态变量等
- bss:未初始化段,记录了程序里要使用但未分配空间的变量 可以这么认为,data段和bss段相比data段既有名字又有空间,bss则只给了名字,空间没分。section有两个属性:
- 可加载(loadable):目标文件里包含的text段和data段,装载器只要把内容装载到相应的地址就能执行;
- 可分配(allocatable):意味着需要给相应的bss段分配空间 对于目标文件都有两个地址:
- LMA:Load Memory Address,加载输出文件时section所在的地址
- VMA:Virtual Memory Address,执行输出文件时section所在的地址 一般而言,某section的VMA==LMA。但在嵌入式系统中,经常存在加载地址和执行地址不同的情况:比如将输出文件加载到开发板的flash中(由LMA指定), 而在运行时将位于flash中的输出文件复制到SDRAM中(由VMA指定)。 因此,linker(链接器)的作用就是:把LMA写到输出的二进制目标文件中,扫描扫描解析输入文件中的符号转换到相应的运行地址上(VMA),而装载器作用是:读取linker输出的二进制文件中相应section信息,装载到LMA地址处,如果发现LMA与VMA不同,就要把data、text等从刚才的LMA处搬到VMA处,这样程序运行的时候才能在VMA处找到相应的变量,程序得以正确运行。
1.2 链接文件常见项
- SECTIONS命令:告诉ld如何把输入文件的sections映射到输出文件的各个section: 如何将输入section合为输出section; 如何把输出section放入程序地址空间(VMA)和进程地址空间(LMA)
- ENTRY(SYMBOL) : 将符号SYMBOL的值设置成入口地址,进程执行的第一条用户空间的指令在进程地址空间的地址
- MEMORY命令:在默认情形下, 连接器可以为section分配任意位置的存储区域,需指定ORIGIN和LENGTH,一般为ram地址
2 crt0.s
首先这是一个c运行库源代码文件,汇编指令形式,需要编译器一块编译。在其中实现cpu初始化、把程序从flash搬移到ram、启动判断等。如果要实现固件更新等操作就一定会用到这个文件了。手边没现成的,先写到这里了就。
链接文件和crt0.S基础
最新推荐文章于 2021-08-12 16:18:15 发布