一. 为什么需要链接脚本
1.1. 从源码到可执行程序(主要有三个步骤: 预编译, 编译, 链接)
1.1.1. 预编译
a. 预编译器执行. 譬如 C 中的宏定义就是由预编译器处理, 注释等也是由预编译器处理的.
1.1.2. 编译
a. 由编译器来执行. 把源码. c .S 编程机器码. o 文件. 所以可以看到每个源码. s .c 文件编译后都有相对应的. o 文件
1.1.3. 链接
a. 由链接器来执行. 把. o 文件中的各函数 (段) 按照一定规则 (链接脚本来指定) 累积在一起,
形成可执行文件.
1.2. 链接脚本究竟要做什么?
1.2.1. 链接脚本其实是个规则文件,
a. 他是程序员用来指挥链接器工作的. 链接器会参考链接脚本, 并且使用其中规定的规则来处理. o 文件中那些段, 将其链接成一个可执行程序.
1.2.2. 常见链接脚本命令
1.2.2.1 ENTRY(SYMBOL)
a. 将 SYMBOL 的值设置成入口地址. 一般设置为_start
1.2.2.2. OUTPUT(FILENAME)
a. 定义输出文件的名字. 可以用它来指定默认的输出文件名称. 当然我们一般都用手动 - o 进行指定, 如果我们没有进行手动指定的话, 输出文件名称就以这个 FILENAME 为输出文件名.
1.2.2.3. OUTPUT_FORMAT(default, big, little)
a. 定义 3 种输出文件的格式. 若有命令行选项 - EB(大端), 则使用第二个输出格式, 有命令行指定 - EL(小端), 则使用第三个格式. 否则使用默认的 default 输出格式.
1.2.2.4. OUT_ARCH(arch)
a. 设置输出文件的体系架构
1.2.2.5. SECTIONS 命令
a. 最重要的, 最基本的, 也是最主要的命令, 它告诉链接器如何把输入文件的各个 section 输出到目标文件中的各个 section 中去
b. 'SECTIONS'是一个功能很强大的命令. 这里这们会描述一个很简单的使用. 让我们假设你的程序只有代码段, 初始化过的数据段, 和未初始化过的数据段. 这些会存在于'.text','.data'和'.bss'段
SECTIONS 命令的格式如下:
SECTIONS
{
一条或者多条 section-command
或者符号赋值语句
}
section-command 的常见格式如下:
- secname [address] : [AT(LMA)]
- { contents }
PS : 首先中括号的选项是可选的, 可以不写
View Code
1.2.2. 简单示例:
- ENTRY(_start);
- OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm");
- OUTPUT_ARCH(ARM);
- SECTIONS
- {
- . = 0x50008000;
- . = ALIGN(4);
- .text : {
- *(.text);
- }
- . = ALIGN(4);
- .data : {
- *(.data);
- }
- . = ALIGN(4);
- .bss : {
- *(.bss);
- }
- }
- View Code
a. 你使用关键字'SECTIONS'写了这个 SECTIONS 命令, 后面跟有一串放在花括号中的符号赋值和输出节描述的内容.
b. '.' 点号在链接脚本中代表当前位置.
c. '=' 等号代表赋值
d. 第二行定义一个输出段,'.text'. 冒号是语法需要, 现在可以被忽略. 段名后面的花括号中, 你列出所有应当被放入到这个输出段中的输入段的名字. '*'是一个通配符, 匹配任何文件名. 表达式'*(.text)'意思是所有的输
入文件中的'.text'输入段. e. address 表示当连接器执行此程序的时候应该把这个段加载到内存的哪个地址, 此地址大多数情况下和 CPU 执行此处时地址相同, 但当进行重定位是就可以实现链接地址和 CPU 执行地址不同(当然代码必须是位置无关编码)
f. . = ALIGN(4); 表示后面地址按四字节对齐
二. 程序段的概念
2.1. 通用段
2.1.1. 这种是编译器链接器内部定好的, 先天性的名字
2.1.2. 代码段:(.text)
a. 又叫文本段, 代码段其实就是函数编译后生成的东西
2.1.3. 数据段:(.data)
a. 数据段就是 C 语言中有显式初始化为非 0 的全局变量, 以及非 0 静态局部变量
2.1.3. bss 段:(.bss)
a. 又叫 ZI(zero initial)段, 就是零初始化段, 对应 C 语言中初始化为 0 或未初始化的全局变量以及初始化为 0 或未初始化静态局部变量.
2.2. 自定义段
a. 段名由程序员自己定义, 段的属性和特征也由程序员自己定义
三. uboot 链接文件
- /*
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
- OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
- /*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
- OUTPUT_ARCH(ARM)
- ENTRY(_start)
- SECTIONS
- {
- . = 0x00000000;
- . = ALIGN(4);
- .text :
- {
- CPU/s5pc11x/start.o (.text)
- CPU/s5pc11x/s5pc110/cpu_init.o (.text)
- board/samsung/x210/lowlevel_init.o (.text)
- CPU/s5pc11x/onenand_cp.o (.text)
- CPU/s5pc11x/nand_cp.o (.text)
- CPU/s5pc11x/movi.o (.text)
- common/secure_boot.o (.text)
- common/ace_sha1.o (.text)
- CPU/s5pc11x/pmic.o (.text)
- *(.text)
- }
- . = ALIGN(4);
- .rodata : { *(.rodata) }
- . = ALIGN(4);
- .data : { *(.data) }
- . = ALIGN(4);
- .got : { *(.got) }
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
- . = ALIGN(4);
- .mmudata : { *(.mmudata) }
- . = ALIGN(4);
- __bss_start = .;
- .bss : { *(.bss) }
- _end = .;
- }
- View Code
参考《朱老师. 1.2ARM 裸机课件》
参考文献《》
来源: http://www.bubuko.com/infodetail-2912367.html