四、U-boot.lds文件分析 (2011-03-11 08:59)


标签:   style  分类:  uboot2010.09移植


U-boot.lds是一个链接脚本,那什么是链接脚本?链接脚本就是程序链接时的的参考文件,其目的是描述输入文件中各段应该怎么样被映射到输出文件,以及程序运行时的内存布局等等。

在这里我有一个小小的疑问,在顶层的config.mk文件中有一下语句:
  1. ifdef VENDOR
  2. BOARDDIR = $(VENDOR)/$(BOARD)
  3. else
  4. BOARDDIR = $(BOARD)
  5. endif
  6. ifndef LDSCRIPT
  7. #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
  8. ifeq ($(CONFIG_NAND_U_BOOT),y)
  9. LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
  10. else
  11. LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
  12. 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来分析:
  1. OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
  2. OUTPUT_ARCH(arm)
  3. ENTRY(_start)
  4. SECTIONS
  5. {
  6. . = 0x00000000;
  7. . = ALIGN(4);
  8. .text :
  9. {
  10. arch/arm/cpu/arm920t/start.o (.text)
  11. *(.text)
  12. }
  13. . = ALIGN(4);
  14. .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
  15. . = ALIGN(4);
  16. .data : { *(.data) }
  17. . = ALIGN(4);
  18. .got : { *(.got) }
  19. . = .;
  20. __u_boot_cmd_start = .;
  21. .u_boot_cmd : { *(.u_boot_cmd) }
  22. __u_boot_cmd_end = .;
  23. . = ALIGN(4);
  24. __bss_start = .;
  25. .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
  26. _end = .;
  27. }
首先,是讲下第一句,看一段英文,相信大家都看得懂:

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这些关键词完全可以任意定义,因为输出段的实际内容与输出段的命名无关,而至于花括号内的具体内容有关。



主要参考:李无言 一步步写嵌入式操作系统

你可能感兴趣的:(脚本,cmd,output,alignment,linker,嵌入式操作系统)