系统程序的链接过程使用到链接脚本文件,通常情况下链接器都会使用默认的链接脚本文件。内核程序段的位置需要精心设计,所以默认链接脚本就不能使用,段名往往由操作系统独立命令。

链接脚本的主要作用是描述如何输入文件中的各个程序段(数据段、代码段、堆、栈、BSS)部署到输出文件中,并规划输出文件各程序段在内存中的布局。

链接脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
. = 0xffff800000000000 + 0x100000;
.text :
{
_text = .;
*(.text)
_etext = .;
}
. = ALIGN(8);
.data :
{
_data = .;
*(.data)
_edata = .;
}
.bss :
{
_bss = .;
*(.bss)
_ebss = .;
}
_end = .;
}
  • 符号.是一个定位器或位置指针,它用于定位程序的地址或 调整程序的布局位置。. = 0xffff800000000000 + 0x100000就是将定位器设置这个地址处,这个地址是线性地址。
  • OUTPUT_FORMAT(DEFAULT,BIG,LITTLE)。它为链接过程提供DEFAULT(默认)、BIG(大端)、LITTLE(小端)三种输出文件格式。程序链接过程中,若链接使用-EB选项,那么程序将链接成BIG指定的文件格式;如果链接命令中由-EL选项,那么程序将链接成LITTLE指定的文件格式;否则链接成默认模式。此脚本执行将文件的三种输出格式设置位elf64-x86-64格式
  • OUTPUT_ARCH(BFDARCH)指定输出文件的处理器体系结构。
  • ENTRY(SYMBOL)将标识符SYMBOL设置位程序入口,即程序执行的第一条指令所在的地址。
  • SECTIONS关键则负责向链接器描述如何将文件中的各程序段(数据段、代码段、堆、栈、BSS)部署到输出文件中,同时还将规划各程序段在内存中的布局。内核程序的代码段.text起始于线性地址0xffff800000100000处,这个线性地址经过页管理机制转换后,对应的物理地址是0x100000。而链接脚本中的正则表达式*(.text)说明了输出文件的.text程序段保存着所有输入文件的.text程序段。而且.text程序段还使用了_text_etext标识符来表示.text程序段的起始线性地址和结束线性地址,这两个标识符可在程序中通过代码extern _textextern _etext进行引用(可以看作全局变量)。此处的符号.表示程序定位器的当前位置(线性地址)。
  • ALIGN(NUM)将地址向后按NUM字节对齐