ld链接脚本的编写

链接命令

链接脚本描述了要连接的文件以及链接顺序,和链接首地址

我们在链接脚本的时候经常会使用如下的语句

ld -Ttext 0x87800000 -o led.elf led.o mian.o gpio.o

其中

ld是链接命令

-Ttext 0x87800000 是链接选项,这个选项是指定将程序的text段加载到0x87800000指定内存地址

-o led.elf是链接选项,是生成的可执行文件

led.o mian.o gpio.o 是需要链接的程序

链接选项

这样的命令参数有很多,比如

-e 使用指定的符号作为程序的入口

-l 把指定的路径添加添加到搜索库的目录清单

-O 对于非零的优化等级,ld将优化输出。在涉及到硬件操作时,不要优化!!!

-o 指定输出文件的名称

-Ttext=使用指定的地址作为文本段的起始点

-Tdata=使用指定的地址作为数据段的起始点

-Tbss=使用指定的地址作为bss段的起始点

等等,还有很多不在一一列举,但是我们发现最后三个命令其实都是为了指定相关段的地址的,如果复杂一些的话,就需要用到链接脚本了,链接脚本可以帮助我们描述代码、数据段的起始地址、大小、对齐方式以及如何处理符号表、重定位表等信息。

链接脚本

上面语句中我们是通过“-Ttext”来指定链接地址是0X87800000的,这样的话所有的文件都会链接到以0X87800000为起始地址的区域。但是有时候我们很多文件需要链接到指定的区域,或者叫做段里面,比如在Linux里面初始化函数就会放到init段里面。因此我们需要能够自定义一些段,这些段的起始地址我们可以自由指定,同样的我们也可以指定一个文件或者函数应该存放到哪个段里面去。要完成这个功能我们就需要使用到链接脚本,看名字就知道链接脚本主要用于链接的,用于描述文件应该如何被链接在一起形成最终的可执行文件。其主要目的是描述输入文件中的段如何被映射到输出文件中,并且控制输出文件中的内存排布。比如我们编译生成的文件一般都包含text段、data段等等。

链接脚本的语法很简单,就是编写一系列的命令,这些命令组成了链接脚本,每个命令是一个带有参数的关键字或者一个对符号的赋值,可以使用分号分隔命令。

我们举个例子,现在将代码链接到0X10000000这个地址,数据链接到0X30000000这个地方。

SECTIONS{.=0X10000000;.text :{*(.text)}.=0X30000000;.data ALIGN(4):{*(.data)}.bss ALIGN(4):{*(.bss)}
}

第2行的"."叫做定位计数器,默认的定位计数器为0。我们要求代码链接到以0X10000000为起始地址的地方,因此这一行给“.”赋值0X10000000,表示以0X10000000开始,后面的文件或者段都会以0X10000000为起始地址开始链接。

第3行的“.text”是段名,后面的冒号是语法要求,冒号后面的大括号里面可以填上要链接到“.text”这个段里面的所有文件,*(.text)中的*是通配符,表示所有输入文件的.text段都放到.text中。

第4行,我们的要求是数据放到0X30000000开始的地方,所以我们需要重新设置定位计数器。

第5行,很像第3行,但是多了一个 ALIGN(4),意思是对.data这个段的起始地址做字节对齐的,ALIGN(4)表示4字节对齐,一般常见的都是ALIGN(4)或者ALIGN(8)

第6行,定义了一个.bss段,所有文件中的.bss数据都会被放到这个里面,.bss数据就是那些定义了但是没有被初始化的变量。

使用链接脚本

我们写一个稍微复杂的链接脚本myld.lds

SECTIONS {. = 0x87800000;.text :{main.o    *(.text)}.rodata ALIGN(4):{*(.rodata*)}.data ALIGN(4):{*(.data)}__bss_start =.;.bss ALIGN(4):{*(.bss)*(COMMON)}__bss_end =.; 
}

这个链接脚本设置链接到开始位置的文件为start.o,因为main.o里面包含着第一个要执行的指令,所以一定要链接到最开始的地方。

__bss_start__,__bss_end__是符号,第11、13这两行其实就是对这两个符号进行赋值,其值为定位符 .,这两个符号用来保存.bss段的起始地址和结束地址。bss段是定义了但是没有被初始化的变量,我们需要手动对.bss段的变量清零的。bss段的起始地址和结束地址就保存在了__bss_start__,__bss_end__中,我们就可以直接在汇编或者C文件里面使用这两个符号。

我们的链接命令就变为了

ld -Tmyld.lds -o led.elf led.o mian.o gpio.o

本文链接:https://my.lmcjl.com/post/13020.html

展开阅读全文

4 评论

留下您的评论.