IMX6ULL裸机学习(7)— 使用链接脚本链接代码
一、链接脚本的作用
链接脚本的作用就是用来指定程序的链接方式的,一个程序中包含各种文件,例如start.o、main.o、led.o等,每个文件有包含如代码段、数据段等各种段,而链接脚本的作用就是用来指定各种文件各种段的链接方式。前面我们都没有使用链接文件,只使用了-Ttext
参数来指明代码段的链接地址,其他都是按照默认链接的,使用之前曾强调要将start.o
文件放在最前面。
二、编写链接文件
将Makefile中的链接命令该为如下所示
$(LD) -g -T imx6ull.lds $^ -o $(BUILD_DIR)/$(TARGET).elf
接着编写一个最简单的链接文件imx6ull.lds
如下所示,其实这个和之前的-Ttext 0x80100000
参数效果是一样的。首先SECTIONS {}
是链接文件的语法,表示程序的所有段都在其中;然后. = 0x80100000
表示当前地址设置为0x80100000,亦即链接的起始地址为0x80100000
;. = ALIGN(4)
表示当前地址按4字节对齐;.text
表示段名,*(.text)
表示将所有文件的代码段都存放在此。
SECTIONS {
. = 0x80100000;
. = ALIGN(4);
.text :
{
*(.text)
}
}
我们打开反汇编文件,可以看到段名为.text
的段
三、修改段名
其实段名是可以由自己定义的,如下所示,修改.text
的段名
打开make执行后打开反汇编文件可以看到其段名也变了
四、指定文件链接顺序
其中*(.text)
中的*
是通配符表示所有文件,我们其实可以也可以写明哪一个文件,如下所示
然后看反汇编文件,main.o的代码被放到了最前面,实际上这样是不能用的,因为我们要从start.s开始执行
所以我们要修改为如下所示,这样不管链接时文件怎样排列,start文件都是在最前面
五、添加其他段
添加只读数据段、数据段、BSS段后如下所示
SECTIONS {
. = 0x80100000;
. = ALIGN(4);
.text :
{
*start.o (.text)
*main.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : {
*(.rodata) }
. = ALIGN(4);
.data : {
*(.data) }
. = ALIGN(4);
__bss_start = .;
.bss : {
*(.bss) *(.COMMON)}
__bss_end = .;
}
然后修改main程序添加如下全局变量
然后make编译,打开反汇编文件,找到如下所示,可以看到这三个段分别存放着刚刚定义的C语言中的全局变量,只读数据段中放置加const
修饰的变量,BSS段放置未初始话或初始化为零的全局变量,数据段放置其他已初始化的全局变量。注意myzero1
找不到是因为其放置在bss段的开始位置,被__bss_start
标签覆盖了,这就是为什么要写两个初始化为零的全局变量的原因。