linux .bin文件生成6,第六章 ELF文件生成bin文件的处理方法--嵌入式linux中文站

嵌入式linux中文站在线图书

第六章 ELF文件生成bin文件的处理方法

_etext = . ;

} > rom

.data : {

_sdata = . ;

*(.data)

*(.glue_7*)

. = ALIGN(4);

_edata = . ;

} > ram

.bss : {

_sbss = . ;

*(.bss)

. = ALIGN(4);

_ebss = . ;

} > ram

}

可见,就内存空间的安排而言,.text段放在rom里,而.data放在ram里。具体分布如下:

---------------- 0x0000

0000

.text

----------------

...

---------------- 0x2000 0000

.data

---------------- (0x2000 0000 + sizeof(.data))

.bss

----------------

也就是说,.text和.data段的地址是不连续的,.data段和.bss则是连续的。而ELF具有可执行属性的段只有.text和.data。objcopy如果直接采用-O binary选项,实际上是解析ELF文件信息,然后复制.text段首地址到.data的段尾地址。很明显,像地址不连续的情况,就会出现空洞。如boot,空洞会相当大,根本不适合下载。下面根据Linux下工具进行具体分析。

[armlinux@lqm boot]$

arm-linux-readelf -a boot > elfinfo.txt

这样可以得到生成的ELF文件的所有信息。主要信息如下:

Section Headers:

[Nr] Name Type Addr Off Size ES Flg Lk Inf Al

[ 0] NULL 00000000 000000 000000 00 0 0 0

[ 1] .text PROGBITS 00000000 000074 002744 00 AX 0 0 4

[ 2] .data PROGBITS 20000000 0027b8 0001c4 00 WAX 0 0 4

[ 3] .bss NOBITS 200001c4 00297c 00841c 00 WA 0 0 4

[ 4] .comment PROGBITS 00000000 00297c 000098 00 0 0 1

[ 5] .shstrtab STRTAB 00000000 002a14 000035 00 0 0 1

[ 6] .symtab SYMTAB 00000000 002b8c 000710 10 7 53 4

[ 7] .strtab STRTAB 00000000 00329c 0003e0 00 0 0 1

Key to Flags:

W (write), A (alloc), X (execute), M (merge), S (strings)

I (info), L (link order), G (group), x (unknown)

O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:

Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align

LOAD 0x000074 0x00000000 0x00000000 0x02744 0x02744 R E 0x4

LOAD 0x0027b8 0x20000000 0x20000000 0x001c4 0x085e0 RWE 0x4

Section to Segment mapping:

Segment Sections...

00 .text

01 .data .bss

可以看出,.text从0x0000 0000开始,大小为0x2744Bytes,.data从0x2000 0000开始,大小为0x1c4.生成的bin文件应该为(0x2744+0x01c4)=0x2908=10504 Bytes。这个可以用ls -l来验证。不过,采用这种方式,需要在程序中进行处理,主要任务就是完成代码的搬移和bss的清0处理。这也就是crt0.S的作用。

[armlinux@lqm boot]$ cat

crt0.S

@ r0 -> start of flash

@ r1 -> where to load data

@ r2 -> start of program

.text

.align

.global main,_main

main:

_main:

# copy .data section

ldr r3, =_etext

ldr r4, =_sdata

ldr r5, =_edata

subs r5, r5, r4

bl copydata

# clear .bss section

ldr r4, =_sbss

ldr r5, =_ebss

subs r5, r5, r4

mov r0, #0

bl clearbss

# and jump to the kernel

b boot

copydata:

subs r5, r5, #4

ldr r6, [r3], #4

str r6, [r4], #4

bne copydata

mov pc, lr

clearbss:

subs r5, r5, #4

str r0, [r3], #4

bne clearbss

mov pc, lr

代码比较简单,不做分析。(二)以自修改的at91rm9200 loader为例,介绍方法二

all: loader.bin

loader.bin: $(OBJ)

$(LD) $(LDFLAGS) $^ -o loader

$(OBJCOPY) -O binary loader $@

链接设置如下:

[armlinux@lqm loader]$ cat

ld.script

MEMORY {

ram : ORIGIN = 0x200000, LENGTH = 0x3000

}

SECTIONS {

.text : {

_stext = . ;

*(.text)

*(.rodata)

. = ALIGN(4);

_etext = . ;

} > ram

.data : {

_sdata = . ;

*(.data)

*(.glue_7*)

. = ALIGN(4);

_edata = . ;

} > ram

.bss : {

_sbss = . ;

*(.bss)

. = ALIGN(4);

_ebss = . ;

} > ram

}

可见.text和.data的地址是连续的。这样,原来的loader代码中文件crt0.S是没有必要的。boot如果采用方法二的处理方法,生成的bin文件为0x2000

01c4,可以很容易验证。理解了这些,在自己设计boot loader时,就会综合考虑链接器设置的内存空间分配和bin生成方式选择。显然,方法一适合.text和.data地址不连续的情况,方法二适 合.text和.data地址连续的情况。分析清楚了这些,也解决了原来在s3c2410设计实验程序时出现的生成bin文件过大的问题了。解决这个问题后,对官方的loader和boot程序做了一些修正,其实因为对U-boot做了启动位置无关性的改进后,boot程序没有什么必要了,但还是备份一下,算是对工作的一个总结吧。AT91RM9200 kernel之前的引导加载程序就比较完善和稳定了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值