4.链接器脚本
4.链接器脚本
一、体验:
首先先看一个例子:图1-1:
编译烧写的过程:
main.c的截图:
可以看到在main函数中点亮了第一个盏灯:
图1-1 点灯
在这个例子中的gboot.lds的代码为:
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS {
. = 0x50008000;
. = ALIGN(4);
.text :
{
start.o (.text) //.text指明的是代码段,代码段里指定第一个执行的文件是start.o.
//接下来改变这个文件,改为main.o的运行结果如下。图1-2
*(.text)
}
. = ALIGN(4);
.data :
{
*(.data)
}
. = ALIGN(4);
bss_start = .;
.bss :
{
*(.bss)
}
bss_end = .;
}
当在lds文件里改变第一个运行的文件后的截图:图1-2:
Gboot.lds代码:
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS {
. = 0x50008000;
. = ALIGN(4);
.text :
{
main.o (.text)//改变为main.o为第一个运行的文件。结果等点不亮。图1-2:
*(.text)
}
. = ALIGN(4);
.data :
{
*(.data)
}
. = ALIGN(4);
bss_start = .;
.bss :
{
*(.bss)
}
bss_end = .;
}
图1-2
这就是链接器脚本的作用,能够影响整个工程的结果。下面对链接器脚本进行介绍。
二、链接器脚本:
链接器脚本的构成:
-
基本构成是:段
-
起始链接地址
-
对齐
-
变量
-
代码段首文件
一个可执行程序通常包括:代码段,数据段,bss段。由此,一个链接器用于链接这个程序,就会反映这几个段的信息。
SECTIONS {//固定格式
. = 0x50008000;//.点表示程序的起始地址,现在设置程序运行的起始地址是0x50008000
//可以反汇编查看程序运行的起始地址图1-3:
. = ALIGN(4);//设置四字节对齐,就是地址能整除4。这是因为ARM访问内存是4字节
//对齐的,为了提高效率,所以在存放数据的时候做到4字节对齐。所以ALIGN(4)的功
//能就是使当前的地址调整为四字节对齐。例如当前的地址是1,它会自动加上3,变
//四字节对齐。
.text :
{
start.o (.text) //设置段首文件为start.o,就是上电第一个运行的代码。
*(.text) //.text代码段,代码段是所有文件(*)的代码段
}
. = ALIGN(4);
.data :
{
*(.data) //.data数据段,数据段是所有文件(*)的数据段
}
. = ALIGN(4);
bss_start = .;//链接器脚本的变量,记录当前的地址
.bss : //bss段开始
{
*(.bss) //.bss段,bss段是所有文件(*)的bss段
}
bss_end = .; //链接器脚本的变量,记录当前的地址。通过与前面的bss_start的差就是这
//bss段的大小。
}
查看程序运行的起始地址确实是0x50008000:图1-3:
图1-3
这里,只要知道可以从这里改变程序的起始链接地址就可以了。后面会讲该操作的重要性。
这些就是lds链接文件的基本知识。