u-boot-1.1.6源码学习主要讲述和总结了本人在学习u-boot中的每个步骤,由于水平有限,难免有误,欢迎指正。
5. u-boot源码分析——第一阶段之链接文件u-boot.lds
分析代码当然要从上电后执行的第一条指令开始看起咯, 那第一条指令在哪呢?在这里以smdk2410为例,我们看它的链接脚本:
即:board/smsk2410/u-boot.lds
对于.lds文件,它定义了整个程序编译之后的连接过程,决定了一个可执行程序的各个段的存储位置.
先看一下GNU官方网站上对.lds文件形式的完整描述:
SECTIONS { ... secname start BLOCK(align)(NOLOAD): AT (ldadr ) {contents } >region :phdr=fill ... } |
secname和contents是必须的,其他的都是可选的。下面挑几个常用的看看:
1、secname:段名
2、contents:决定哪些内容放在本段,可以是整个目标文件,也可以是目标文件中的某段(代码段、数据段等)
3、start:本段连接(运行)的地址,如果没有使用AT(ldadr),本段存储的地址也是start。GNU网站上说start可以用任意一种描述地址的符号来描述。
4、AT(ldadr):定义本段存储(加载)的地址。
看一个简单的例子:
/* nand.lds */ SECTIONS { firtst 0x00000000 :{ head.o init.o } second 0x30000000 : AT(4096){ main.o } } |
以上,head.o放在地址0x00000000处运行,init.o放在head.o后面,它们的存储地址也是0x00000000处,即运行地址和存储地址相同(没有AT指定)。main.o放在4096(即0x1000,是AT指定的存储地址)开始处,但它的运行地址是在0x30000000,运行之前,需要先从0x1000(存储处)复制到0x30000000(运行处),此过程也就用到了读取NandFlash。
board/smsk2410/u-boot.lds:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32littlearm")
# 指定输出可执行文件是elf格式,32位ARM指令,小端
OUTPUT_ARCH(arm) # 指定输出可执行文件的平台为ARM
ENTRY(_start) # 指定输出可执行文件的起始代码段为_start
SECTIONS
{
. = 0x00000000; # 从0x0位置开始
. = ALIGN(4); # 以4字节对齐
.text : # 代码段
{
cpu/arm920t/start.o (.text) # 这个是启动后第一个执行的代码,即start.S文件
*(.text) #其它的代码部分放在这里
}
. = ALIGN(4); # 以4字节对齐
.rodata : { *(.rodata) } # 只读数据段
. = ALIGN(4);
.data : { *(.data) } # 读、写数据段
. = ALIGN(4);
.got : { *(.got) } # got段式是uboot自定义的一个段,非标准段
. = .;
__u_boot_cmd_start = .; # 把__u_boot_cmd_start赋值为当前位置,即起始位置
.u_boot_cmd : { *(.u_boot_cmd) } # u_boot_cmd段, uboot把所有的uboot命令放在该段
__u_boot_cmd_end = .; # 把__u_boot_cmd_end赋值为当前位置,即结束位置
. = ALIGN(4);
__bss_start = .; # 把__bss_start赋值为当前位置,即紧挨着uboot命令段
.bss : { *(.bss) } # 指定bss段
_end = .; # 把_end赋值为当前位置,即bss段的结束位置
}
阅读(127) | 评论(0) | 转发(0) |