- 论坛徽章:
- 0
|
[color="#02368d"]AT91RM9200开发笔记(6):ELF文件生成bin文件的处理方法
文章说明:calmarrow(lqm)原创
文章引自:
http://piaoxiang.cublog.cn
题记:
解决了两种情景下ELF文件转化为binary格式,固化到flash中启动的问题,对链接器和加载器原理又有了一个更为深入的认识。结合该问题,对AT91RM9200的官方loader和boot做了些修正。
在嵌入式系统中,固化到非易失性存储介质中的软件是binary格式。Linux下生成的可执行文件是ELF格式,不能直接固化,必须转化为bin文件。就处理方法而言,视链接方式不同,可以有两种不同的方法,下面分别举例说明。
(一)以at91rm9200 boot官方程序为例,介绍方法一
boot最终得到boot.bin,为bin文件,可以直接固化到NVM中。它有两个组成部分:boot.text和boot.data。处理方式如下:
all: boot.bin
boot.bin: boot.text boot.data
cat $^ > $@
boot.text: boot
$(OBJCOPY) -O binary -j .text $ $@
boot.data: boot
$(OBJCOPY) -O binary -j .data $ $@
boot: $(OBJ)
$(LD) $(LDFLAGS) $^ -o $@
下面看一下链接器的设置。
[armlinux@lqm boot]$ cat ld.script
MEMORY {
ram : ORIGIN = 0x20000000, LENGTH = 0xf000
rom : ORIGIN = 0x00000000, LENGTH = 0xf000
}
SECTIONS {
.text : {
_stext = . ;
*(.text)
*(.rodata*)
. = ALIGN(4);
_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程序没有什么必要了,但还是备份一下,算是对工作的一个总结吧。
![]()
文件:
myloader.tar.gz
大小:
57KB
下载:
下载
![]()
文件:
myboot.tar.gz
大小:
51KB
下载:
下载
至此,AT91RM9200 kernel之前的引导加载程序就比较完善和稳定了。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/63379/showart_503654.html |
|