uboot起步

来源:互联网 发布:js字符串split 编辑:程序博客网 时间:2024/05/17 01:39

基本链接脚本的概念

我们需要一些词汇和概念描述链接脚本语言。

链接器将多个输入的文件合成为一个单独的输出文件。这个输出文件和多个输入的文件都是有特定的的数据格式,被称为目标文件。输出文件通常是可执行,我们在这里也称之为目标文件。每个目标文件都由多个段组成。我们通常认为一个输入文件称为输入段,输出文件是一个输出段。

在目标文件中,每个段都有一个名字和大小。大多数的段都由一个数据块,称为数据段。数据段可能被加载,意味着当输出文件运行时,数据应该被加载到内存。一个没有数据的段,可能需要分配内存,意味着这个内存应该设置边界,但是不应该加载任何数据(通常情况下这个内存必须被初始化为0)。一个既不需要加载也不需要分配内存的段通常包含一些调试信息

任何可加载或可分配的段有两个地址。一个是虚拟内存地址(VMA, virtual memory address),另外一个是加载内存地址(LMA, load memory address)。虚拟内存地址是这个段在输出文件运行时候的地址,加载内存地址是这个段被装载的地址。大多数情况下,这两个地址是相同的。一个可能不一样的例子是,当一个数据段加载到ROM,并且拷贝到程序启动的RAM(这个技术通常用于一个基于ROM的系统初始化全局变量)。这种情况下,ROM的地址可能是加载地址,ROM的地址可能是虚拟内存地址。

你可以通过使用objdump程序的’-h’选项查看目标文件中的段。

每个目标文件有一系列符号,被称为符号表。一个符号可能被定义或者未定义。每一个符号有个名字,每个定义的符号有个地址。如果你编译C或者C++程序为一个目标文件,你将会得到每个为定义的函数和全局静态变量定义的符号,每个未定义的函数或者全局变量在输入文件中的将会变成一个未定义符号。

你可以通过使用 nm程序或者使用objdump的’-t’选项查看符号表


链接格式

链接脚本是文本文件。

链接脚本又一系列的命令组成。每个命令是一个关键字,可能带参数,或者一个分配的符号。你可能使用分号分割多个命令。空格通常被忽略。

字符串,例如文件名或者格式化名称通常可以直接输入。如果一个文件名包含一个字符,例如逗号可能会分割文件名,你可以输入这个文件名时使用双引号。在一个文件名中如果包含了双引号是没有办法处理的。

你可以在链接脚本中包含注释,例如c语言的限定符’/‘和’/’。在C中,注释在语法中等价于空白。


简单的链接脚本例子

许多链接脚本相当简单。

最简单的链接脚本只有一个命令:‘SECTIONS’。你使用‘SECTIONS’命令描述输出文件的内存布局。

‘SECTIONS’命令相当强大。这里我们描述一个简单的用法。我们假设你的程序只是由代码、初始化数据和未初始化数据,这些分别将会在’.text’, ‘.data’和’.bss’段。我们假设在输入文件中之出现这三个段。

对于这个例子,让我们把代码加载到地址0x10000, 数据开始于地址0x8000000,.下面这个链接脚本将会做到:

 SECTIONS     {       . = 0x10000;       .text : { *(.text) }       . = 0x8000000;       .data : { *(.data) }       .bss : { *(.bss) }     }

你先写‘SECTIONS’命令作为关键字,后边跟着一个大括号包起来的一系列符号分配和输出段描述。

在上边例子‘SECTIONS’命令内部的第一行设置了一个‘.’符号的值,它是位置计数器。如果你没有以一些别的方式(别的方式后边说明)指定输出段的地址,这个地址是设置当前的位置计数器的值。位置计数器根据输出文件的段增长。在’SECTIONS‘命令的开始,位置计数器的值为0。

第二行定义了一个’.text’段。冒号按语法是必须的,当前可以忽略它。后边跟着一个大括号,通常包含输出段的名字,你列出的输入段将会替换成输出段。’‘是个通配符用来匹配任何文件名。表达式’(.text)’表示所有的在输入文件中的所有的输入段中的’text’段。

因此,当输出段’text’段别定义到位置计数器‘0x10000’,链接器会把输出文件的’.text’段设置到地址’0x10000’。

剩下的行定义输出文件的’.data’和‘.bss’段。链接器将会把’.data’输出段放到地址’0x8000000’。在’.data’输出段放完,位置计数器的值将会加上地址’0x8000000’和‘.data’的输出段大小。这将会立即影响到输出文件’.data’段后的’.bss’段在内存中的位置。

通过增加位置计数器,链接器会确保每个输出段按字节对齐。在这个例子中,指定‘.text’和’.data’段大概满足字节对齐约束。但是链接器可能在’.data’和’.bss’段中间产生间隙。

这就是一个简单的完整的链接脚本。


简单的链接脚本命令

本节介绍简单的链接脚本命令

入口点

第一条指令别称为可执行程序的入口点(entry point)。你可以使用 ENTRY 链接脚本命令设置入口点。内容提要是一个符号名:
ENTRY(symbol)
有很多方法设置入口点,链接器将会按照下列方法的顺序设置入口点,并且在其中一种设置成功后停止下一种:

  • 使用‘-e’ 入口命令选项;
  • 链接脚本中使用ENTRY(symbol)命令;
  • 指定的符号链接值,如果被定义;对于多个目标这是个开始,但是PE和BeOS基础的系统需要检查符号链接,匹配第一个。
  • ‘.text’段的第一个字节的地址;
  • 地址0

文件命令

一些处理文件的命令

INCLUDE filename
包含连接器脚本文件名在这个点,这个文件将会在本目录下查找,使用 -L 选项指定路径,你可以嵌套调用 INCLUDE 10层深。
你可以将INCLUDE指令放置在最外层,在MEMORY 或者 SECTIONS命令内部,或者在输出段描述中。

to be continues……………..
INPUT(file, file …)

GROUP(file, file …)

AS_NEEDED(file, file …)

OUTPUT(filename)

SEARCH_DIR(path)

STARTUP(filename)

格式命令

区域别名

其他连接脚本命令


分配值和符号


SECTIONS命令


内存命令


PHDRS命令


版本命令


链接脚本中的表达式


链接脚本的暗示


ld 和 ARM家族


本文参考

1. Basic Linker Script Concepts
2. Linker Script Format
3. Simple Linker Script Example
4. Simple Linker Script Commands

0 0
原创粉丝点击