在自己写简单BootLoader时发现了一个问题,lds文件中未指定.text段时各文件的存放顺序,但是u-boot内的lds有指定text段最开始要存放start.o。
网上查了很久未指定.text段时各文件的存放顺序,直到论坛上有个人回答了我。
makefile中的objs顺序代表了编译顺序。
带着疑问我做了几个试验。
原先的makefile和lds文件内容
CC = arm-linux-gcc
LD = arm-linux-ld
AR = arm-linux-ar
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump
CFLAGS := -Wall -O2
CPPFLAGS := -nostdinc -nostdlib -fno-builtin
objs :=start.o init.o boot.o
boot.bin :$(objs)
${LD} -Tboot.lds -o boot.elf $^
${OBJCOPY} -O binary -S boot.elf $@
${OBJDUMP} -D -m arm boot.elf >boot.dis
%.o:%.c
${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
%.o:%.S
${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.o *.bin *.dis *.elf
SECTIONS{
. = 0x33f80000; /*链接地址*/
.text : {*(.text)} /*代码段*/
. = ALIGN(4); /*下一段的起始地址向4取整*/
.rodata : {*(.rodata*)} /*只读数据段*/
. = ALIGN(4);
.data : {*(.data)} /*数据段*/
. = ALIGN(4);
__bss_start = .; /*bss段起始地址设为当前地址*/
.bss : {*(.bss) *(COMMON) } /*bss段 以及通用符号段*/
__bss_end = .;
}
1)修改makefile文件的obj依赖顺序
objs := init.o start.o boot.o
//make时输出信息如下
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o init.o init.c
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o start.o start.S
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o boot.o boot.c
arm-linux-ld -Tboot.lds -o boot.elf init.o start.o boot.o
arm-linux-objcopy -O binary -S boot.elf boot.bin
arm-linux-objdump -D -m arm boot.elf >boot.dis
可以通过编译,但是烧录进板子无法启动内核
2)在修改完obj依赖顺序的基础上修改lds文件指定存放顺序
SECTIONS{
. = 0x33f80000; /*链接地址*/
.text : {
start.o (.text) //指定start.o放在代码段最开始
*(.text)
} /*代码段*/
. = ALIGN(4); /*下一段的起始地址向4取整*/
.rodata : {*(.rodata*)} /*只读数据段*/
. = ALIGN(4);
.data : {*(.data)} /*数据段*/
. = ALIGN(4);
__bss_start = .; /*bss段起始地址设为当前地址*/
.bss : {*(.bss) *(COMMON) } /*bss段 以及通用符号段*/
__bss_end = .;
}
可以通过编译且烧录后可以正常启动内核
结论确实如论坛这位老师所说的一样,不过我感觉可以引申为:
当代码段未指定存放顺序时,代码段存放顺序按编译时的链接顺序存放
。
版权声明:本文为qq_17270067原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。