Chinaunix首页 | 论坛 | 博客
  • 博客访问: 595751
  • 博文数量: 99
  • 博客积分: 5128
  • 博客等级: 大校
  • 技术积分: 1538
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-27 19:40
文章分类

全部博文(99)

文章存档

2012年(3)

2011年(5)

2010年(4)

2009年(31)

2008年(56)

分类: LINUX

2009-03-24 11:26:27

Linker Scripts

Ld --verbose 可以查看默认的连接脚本

 

VMA, or virtual memory address 运行地址

LMA, or load memory address 装载地址

 

Objdump –h 参数可以查看 section

 

 

(一)一个最简单的例子

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

 

1,  SECTIONS 是最重要的命令,必须包含。

2,  . 表示当前地址值,这个地址是运行时地址,也就是 VMA

 

Entry point

The first instruction to execute in a program is called the entry point

第一条执行的指令叫 entry point

ENTRY(symbol)

 

Ld按照如下的顺序确认entry point

1-e 参数指定。

3,ENTRY(symbol)符号指定的地址
4,Start符号的定义
5,.text 中的第一条指令
6,地址0
 
处理文件包含
INCLUDE filename

查找当前目录,还有-L 指定的搜索目录,include可以嵌套最多10层。

 

 

floating_point = 0;
SECTIONS
{
  .text :
    {
      *(.text)
      _etext = .;
    }
  _bdata = (. + 3) & ~ 3;
  .data : { *(.data) }
}

 

定义符号的用法。

_bdata = (. + 3) & ~ 3;  下一个4字节对齐地址的用法。

 

 

完整的 section 的定义是,

section [address] [(type)] : [AT(lma)]
  {
    output-section-command
    output-section-command
    ...
  } [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp]

 

 

地址 VMA的分配

.text . : { *(.text) }
.text : { *(.text) }

两个表达式不完全相同,第一个是分配当前地址,而第二个确实分配当前的对齐地址。

 

如果需要边界对齐,可以用下面的:

.text ALIGN(0x10) : { *(.text) }

 

ALIGN(0x10) 会将地址值向前增加,直到 0x10 字节对齐为止。

 

 

Input Section Description

*(.text)

最简单的形式,匹配所有文件所有的 .text

 

(*(EXCLUDE_FILE (*crtend.o *otherfile.o) .ctors))

包含除了*crtend.o   *otherfile.o 中的所有输入object文件的 .ctors

 

*(.text .rdata)
*(.text) *(.rdata)

包含多个段的两种形式,其中第一种表示两个段混合在一起分配,第二种表示先分配所有的 .text 段,然后再分配所有的 .rdata 段。

 

data.o(.data)

指定包含obj文件中的某个段

 

SECTIONS {
  .text : { *(.text) }
  .DATA : { [A-Z]*(.data) }
  .data : { *(.data) }
  .bss : { *(.bss) }
}

 

输入段的通配符的用法。有点类似shell的正则表达式,不过这里很简单。

 

.bss { *(.bss) *(COMMON) }

一般需要包含 COMMON段。

 

--gc-sections garbage section

用来标记没有用的段。连接器可以通过关键字 KEEP 来防止删除。

 

Output Section LMA

LMA的用法,这里比较重要,是设置装在地址的。默认是 VMA LMA是同一个地址的。

 

SECTIONS
  {
  .text 0x1000 : { *(.text) _etext = . ; }
  .mdata 0x2000 :
    AT ( ADDR (.text) + SIZEOF (.text) )
    { _data = . ; *(.data); _edata = . ;  }
  .bss 0x3000 :
    { _bstart = . ;  *(.bss) *(COMMON) ; _bend = . ;}
}

 

例子,   其中ADDR返回的是MVA段的开始地址,SIZEOF返回的是段的大小。

相应的RUN TIME初始化代码可以这样来处理

 

extern char _etext, _data, _edata, _bstart, _bend;
char *src = &_etext;
char *dst = &_data;
 
/* ROM has data at end of text; copy it. */
while (dst < &_edata) {
  *dst++ = *src++;
}
 
/* Zero bss */
for (dst = &_bstart; dst< &_bend; dst++)
  *dst = 0;

 

 

 

阅读(1087) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~