分类: LINUX
2010-09-15 15:00:44
/board/prochip/ub4020/U-boot.lds
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")
;三个分别指定在缺省、大端、小端情况下的输出可执行文件格式,这里都指定输出格式是elf32,小端和arm体系结构。
OUTPUT_ARCH(arm)
;输出可执行文件指定为arm体系结构。
ENTRY(_start)
;指定启动时的函数入口地址,_start在每个CPU目录下的start.S中定义,真正的启动运行地址段由TEXT_BASE宏定义在编译时由config.mk中定义。
SECTIONS
{
. = 0x00000000;
;指定系统启动从偏移地址零处开始。注意这只是个代码地址偏移值,真正的起始地址是由编译时指定的CFLAGS指定的。
;地址进行4字节对齐调整。
.text :
{
cpu/sep4020/start.o (.text) ;定义.text段空间
*(.text) ;后续.text段内容的分配
}
. = ALIGN(4);
;地址进行4字节对齐调整。
.rodata : { *(.rodata) } ;.rodata只读数据段
. = ALIGN(4);
;地址进行4字节对齐调整。
.data : { *(.data) } ;.data可读可写数据段
. = ALIGN(4);
;地址进行4字节对齐调整。
.got : { *(.got) } ;.got段式uboot自定义的一个段,非标准段
. = .;
__u_boot_cmd_start = .; ;把__u_boot_cmd_start赋值为当前位置
;即定义了.u_boot_cmd段空间的开始位置
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .; ; 把__u_boot_cmd_end赋值为当前位置
;即定义了.u_boot_cmd段空间的结束位置
armboot_end_data = .; ;armboot_end_data符号指向之前所有分配完段的结束
. = ALIGN(4);
;地址进行4字节对齐调整。
__bss_start = .; ;.bss段开始位置
.bss : { *(.bss) }
_end = .; ;.bss段结束位置
}
说明1:标准应用程序包括 3 类标准段空间:.text 运行代段;.data 全局变量等具有初始值的数据空间;.bss暂态变量,堆栈等数据空间;
说明 2:.rodata,.got,.u_boot_cmd 等段空间由程序员设计需要而自行定义的段空间;
说明 3:采用 ARM720T CPU 进行分析,其指令字长为 4字节,所以地址调整为 4 字节;
(1)在配置文件config.mk中154定义了CPPFLAGS 变量,其中指定了程序的链接基址为 TEXT_BASE
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) -D__KERNEL__
ifneq ($(TEXT_BASE),)
CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
Endif
(2)在其后又在172行CFLAGS 包含了CPPFLAGS变量
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
(3)然后在主Makefile中将config.mk进来了,这样其中的大部分变量都在编译过程中有固定的值了
# load other configuration
include $(TOPDIR)/config.mk
(4)在生成elf可执行文件u-boot的命令中就指定了链接标志LDFLAGS
$(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT)
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS)
-Map u-boot.map -o u-boot
查看system.map如下:
30700000 t $a
30700000 T _start
30700020 t $d
30700020 t _undefined_instruction
30700024 t _software_interrupt
30700028 t _prefetch_abort
3070002c t _data_abort
30700030 t _not_used
30700034 t _irq
30700038 t _fiq
30700040 t _TEXT_BASE
30700044 T _armboot_start
30700048 T _bss_start
3070004c T _bss_end
30700050 T IRQ_STACK_START
30700054 T FIQ_STACK_START
30700058 t $a
30700058 t reset
30721934 A __u_boot_cmd_start
30721934 d $d
30721934 D __u_boot_cmd_autoscr
还没弄明白
以下是转载的一篇文章
SECTIONS { ... secname start BLOCK(align) (NOLOAD) : AT ( ldadr ) { contents } >region :phdr =fill ... } |
secname和contents是必须的,其他的都是可选的。下面挑几个常用的看看:
/* nand.lds */ SECTIONS { firtst 0x00000000 : { head.o init.o } second 0x30000000 : AT(4096) { main.o } } |
relocate: /* 把U-Boot重新定位到RAM */ adr r0, _start /* r0是代码的当前位置 */ /* adr伪指令,汇编器自动通过当前PC的值算出 如果执行到_start时PC的值,放到r0中: 当 此段在flash中执行时r0 = _start = 0;当此段在RAM中执行时_start = _TEXT_BASE(在board/smdk2410/config.mk中指定的值为0x33F80000,即u-boot在把代码拷贝到RAM中去 执行的代码段的开始) */ ldr r1, _TEXT_BASE /* 测试判断是从Flash启动,还是RAM */ /* 此句执行的结果r1始终是0x33FF80000,因为此值是又编译器指定的(ads中设置,或-D设置编译器参数) */ cmp r0, r1 /* 比较r0和r1,调试的时候不要执行重定位 */ |