GNU链接器(LD):输入分区和输出分区介绍
0 参考资料
GNU-LD-v2.30-中文手册.pdf
GNU linker.pdf
1 前言
一个完整的编译工具链应该包含以下4个部分:
(1)编译器
(2)汇编器
(3)链接器
(4)lib库
在GNU工具链中,对应的是:
(1)编译器:GCC(GNU Compiler Collection,GNU编译器套件)
(2)汇编器:GAS(GNU Assembler,GNU汇编器)
(3)链接器:LD(GNU Linker,GNU链接器)
(4)lib库:glibc(GNU C Library,GNU C 库)
本文介绍GNU链接器(LD)链接器脚本中输入分区、输出分区相关概念。
2 GNU链接器(LD):输入分区和输出分区介绍
实际上输入分区和输出分区密不可分,我们先通过一个简单的链接器脚本对输入分区、输出分区有个感性认识。假设你的程序质包含code(代码)、data(有初始值的数据)、bss(未赋初始值的数据)则它们将被分别放在.text、.data、.bss段中。下面这个例子,会将.text段加载在到0x10000开始的地址,.data段会从0x8000000地址开始,.bss段会紧跟在.data段之后。
SECTIONS
{. = 0x10000;.text : { *(.text) }. = 0x8000000;.data : { *(.data) }.bss : { *(.bss) }
}
在SECTIONS花括号后的第一行,为位置计数器(.)赋值为0x10000,这主要是为了给后面的输出分区.text设置起始地址(如果不通过其它方式给输出分区指定地址),.text是输出分区的名称,后面必须跟冒号(:)。在.text输出分区花括号内列出了想要放在输出分区中的输入分区的名字列表。是通配符,可匹配所有文件名。表达式(.text)意思是将所有输入文件的.text段包含进该输入分区。
由于在定义.text输出分区前已经将位置计数器的值修改为0x10000,且.text输出分区没有定义起始地址,则链接器会将.text输出分区的起始地址设置为0x10000。
接下来的2个输出分区将.data段和.bss段放在了以0x8000000为起始地址的内存空间上。
2 总结
简单来说,输出分区就是告诉链接器如何在存储器(Flash、RAM)中布局,而输入分区则告诉链接器如何映射输入文件到存储布局中。输出分区决定整个分区分配在哪个存储器(或存储器的哪个地址),而输入分区决定code、data、bss段在存储器中的具体布局。