U-boot.lds是一个链接脚本,那什么是链接脚本?链接脚本就是程序链接时的的参考文件,其目的是描述输入文件中各段应该怎么样被映射到输出文件,以及程序运行时的内存布局等等。
在这里我有一个小小的疑问,在顶层的config.mk文件中有一下语句:
- ifdef VENDOR
-
BOARDDIR = $(VENDOR)/$(BOARD)
-
else
-
BOARDDIR = $(BOARD)
-
endif
-
-
ifndef LDSCRIPT
-
#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
-
ifeq ($(CONFIG_NAND_U_BOOT),y)
-
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
-
else
-
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
-
endif
这里可以看出如果定义厂商的话,
BOARDDIR = $(VENDOR)/$(BOARD) 如BOARDDIR = samsung/smdk2410,如果没有定义的话,如BOARDDIR = smdk2410/,然后看
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds 这一句,那么按照这个推理来说u-boot.lds应该在:u-boot-2010.09/board/samsung/smkd2410下才对,但是我在u-boot-2010.09这个版本下并没有发现,看了一下黄刚和
tekkamanninja 的博客,他们都是在cpu/arm920t下找的u-boot.lds,而在uboot1.6版本中/board/samsung/smkd2410是有u-boot.lds的。这一点有疑问,还请知道的指点一下。那下面就贴上u-boot-2010.09\arch\arm\cpu\arm920t目录下的u-boot.lds来分析:
- OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-
OUTPUT_ARCH(arm)
-
ENTRY(_start)
-
SECTIONS
-
{
-
. = 0x00000000;
-
-
. = ALIGN(4);
-
.text :
-
{
-
arch/arm/cpu/arm920t/start.o (.text)
-
*(.text)
-
}
-
-
. = ALIGN(4);
-
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
-
. = ALIGN(4);
-
.data : { *(.data) }
-
-
. = ALIGN(4);
-
.got : { *(.got) }
-
-
. = .;
-
__u_boot_cmd_start = .;
-
.u_boot_cmd : { *(.u_boot_cmd) }
-
__u_boot_cmd_end = .;
-
-
. = ALIGN(4);
-
__bss_start = .;
-
.bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
-
_end = .;
-
}
首先,是讲下第一句,看一段英文,相信大家都看得懂:
You can use OUTPUT_FORMAT with three arguments to use different formats based on the -EB and -EL command line options. This permits the linker script to set the output format based on the desired endianness.
If neither -EB nor -EL are used, then the output format will be the first argument, default. If -EB is used, the output format will be the second argument, big. If -EL is used, the output format will be the third argument, little.
这里既没有用-EB,也没有用-EL指定,那么指定的就是elf32-littlearm 格式,即指定输出文件是elf格式,32位ARM指令,小端模式,
紧接着OUTPUT_ARCH(arm) 指定的是输出可执行文件的运行平台为ARM,
ENTRY(_start)指定_start函数为程序的入口,
SECTIONS这个命令用来描述输出文件的内存布局的,
. = 0x00000000;这里的点号称为位置计数器,通俗的讲,它代表这当前位置,这条语句的意思就是当前位置定义为0地址。
. = ALIGN(4); ALGN勇于产生对齐的代码或数据,因为在一些体系结构对处理对齐的数据或代码时效率更高,这条语句的意思就是位置计数器向高地址方向取最近的4字节的整数倍。
.text :定义了该输出位置为代码段,花括号里定义了代码段的具体内容,arch/arm/cpu/arm920t/start.o (.text)这个指定了start.o文件将出现在代码段的最前面,*(.text)星号代表所有文件,意思是将所有目标文件的代码段都链接到这一区域。
.rodata :定义了只读数据段,
.data :定义了数据段
.got定义了got段,got段是uboot自己定义的一个非标准段
__u_boot_cmd_start = .;将当前位置赋值为__u_boot_cmd_start
这里说明一点:在没有对位置技术器进行赋值时,位置计数器会动态的增加,比如. = .;这一条语句,此时位置技术器的位置就是从0开始加上代码段,只读数据段,数据段,got段的大小,紧接着之后的位置,下面的赋值类似,就不一一详细说明了。
另外还要说明一点:向输出段的定义如:text,rodata,data,got这些关键词完全可以任意定义,因为输出段的实际内容与输出段的命名无关,而至于花括号内的具体内容有关。
主要参考:李无言 一步步写嵌入式操作系统
阅读(2944) | 评论(0) | 转发(3) |