链接脚本,其实是个规则文件. 是程序员用来指导链接器工作的, 链接器会参考链接脚本, 并使启动的使用规定的规则来处理.o文件中的那些段, 将其链接成一个可执行程序.
段: 程序中有分为各个不同的段
段名分为2中: 一种是编译器链接器内部定好的, 这是先天的名字, 另外一种是程序员自己指定的,自定义的段名.
先天性段名
代码段(.text): 又叫文本段, 代码段其实就是函数编译后生成的东西.
数据段(.data), 数据段就是C语言中初始化为非0的全局变量
bss段(.bss), 又叫ZI(zero initial)段,就是零初始化段, 对应C语言中初始化0的全局变量.
后天性段名:
段名由程序员自己定义, 段的属性和特征也由程序员自己定义.
链接脚本的关键内容有2部分: 段名 + 地址(作为链接地址的内存地址)
链接脚本的理解:
SECTIONS{} // 这是整个链接脚本
. 点号在链接脚本中代表当前位置
= 等号代表赋值.
一段脚本代码
SECTIONS
{
. = 0xd0024000; // 表示当前地址 这里为最开始, 程序的开头链接地址为0xd0024000
.text : { // 接着设置代码段 ,
start.o // 首先 将star.o 文件放在所有代码段的前面, 程序将最先执行start.o的程序
* (.text) // 后面跟着所有的.text 属性的文件, 这里就是 把其他程序在start.o程序之后就行
}
.data : {
* (.data) // 这里是数据段, 放着所有的数据段数据
}
bss_start = .; // 这里是将当前的地址赋值给 bss_start 这个标号. 千万不要以为这的 . 是0xd0024000 因为前面已经经过了
// 代码段和数据段, . 已经是0xd0024000 + .text 大小 + .data 大小, 这里赋值给bss_start 应该是给外部使用的.
.bss : {
* (.bss) // 这里放着 .bss的数据
}
bss_end = .; // 同理 将当前地址赋值给bss_end
}
2019年4月16日21:09:45
uboot.lds 链接脚本中的
ENTRY(_start) 用来制定整个程序的入口地址, 所谓入口地址就是整个程序的开头地址, 可以认为就是整个
程序的第一句指令, 有点像C语言中的main
指定程序的连接地址有2中方法, 一种是在Makefile 中ld 的flags用-Ttext 0x20000000来指定,
另外一种是在链接脚本的SECTIONS开头用.=0x20000000 来指定,
两种方法都是可以实现, 但是如果两种方式都同时存在, 那么 起到效果的是-Ttext 0x20000000.
代码段中, 注意文件的排列顺序, 指定必须放在前面部分的那些文件, 就是必须安排在前16KB内的文件, 这些文件中的函数在前16KB会被调用, 在后面第二部分(16KB之后)中调用的程序,前后顺序就无所谓了.