Chinaunix首页 | 论坛 | 博客
  • 博客访问: 52040
  • 博文数量: 17
  • 博客积分: 651
  • 博客等级: 上士
  • 技术积分: 200
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-23 14:23
文章分类

全部博文(17)

文章存档

2011年(10)

2010年(7)

我的朋友

分类: LINUX

2011-01-03 13:19:51

1.什么是链接脚本?
链接器的作用主要有两个:
a.符号的解析
b.符号与地址的绑定
如何解析、如何绑定,这就涉及到链接脚本的作用了。通常链接器都有一个默认的链接脚本,大多数情况下,使用它来链接输入文件,并生成目标文件。我们也可以使用自定义的链接脚本来精确控制目标文件的格式。链接器的"-T"参数就是用来指定链接脚本的。

2.VMA与LMA
VMA:虚拟地址,就是我们通常所讲的虚拟地址
LMA:加载地址,即被加载到内存中的地址
对于应用程序来说,VMA与LMA时一致的。对于内核来说,LMA=VMA-0xC0000000。
内核虚拟地址 = 物理地址 + 0xC0000000。

3.ENTRY条目
指定了入口地址

4.链接脚本符号“.”
“.”是个位置计数器,记录着当前位置在目标文件中的虚拟地址;
“.”是个自动增加的计数器,当一个输出section生成后,会自动加上该section的长度
举例:
. = 0x100000;
_start_addr = .;
.text : {*(.text)}
_end_addr = .;
在此例中,首先给“.”赋初值0x100000,随后又将该值赋给_start_addr,它是.text section的起始地址;接着我们生成了一个.text section,此时"."自动加上该section的长度。
可描述为 . = . + SIZEOF(.text);最后将"."赋给_end_addr,记录下.text section的结束地址。

5.如何构造一个section?
.text.head : AT(ADDR(.text.head) - LOAD_OFFSET){
    _text = .;
    *(.text.head)
} : text = 0x9090

.text.head指定了section的名称;
AT指定了section的加载地址(LMA);
ADDR(section):计算section的虚拟地址;
对于Linux内核,LOAD_OFFSET为0xC0000000;

在此处,LMA = ADDR(.text.head) - LOAD_OFFSET.也就是物理地址;
*(.text.head)完成具体的section创建工作:“*”代表所有的.o输入文件,括号中.text.head指定了链接器感兴趣的sectiong,即所有.o输入文件中的.text.head section都被合并;

_text = . 指定了起始地址
“: text”指定了新生成的section所在的segment
“= 0x9090”指定了section的填充内容,用于代码对齐,0x90是汇编指令中NOP的操作码,故相当于在不连续的代码间填充空操作;

总结:
至此内核的第一个section就创建好了,它名为“.text.head”,由输入文件的.text.head组成,该section的虚拟地址(VMA)由"."的值确定,加载地址(LMA)为物理地址,section中不连续的区域产生的间隙由0x9090填充,最后再将该section放入 text segment中;

6.创建一个section的完整格式

section [address] [(type)] : [AT (lma)]
{
output-section-command
......................
}[>region] [:phdr :phdr...] [= fillexp]
其中:
[address]指定了section的虚拟地址(vma)
若没有指定该参数及region参数,则虚拟地址由"."指定




阅读(1990) | 评论(1) | 转发(0) |
0

上一篇:Makefile基础知识

下一篇:GCC 编译选项

给主人留下些什么吧!~~

chinaunix网友2011-01-04 14:51:54

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com