u-boot链接文件u-boot.lds分析

时间:2022-02-10 09:23:43

转自:http://blog.chinaunix.net/uid-23670869-id-2391614.html

 

对于u-boot-2010.03版本的smdk2410这个平台的链接文件是/cpu/arm920t/u-boot.lds,下面就来分析下该文件的每一句是什么意思。

 

//;三个分别指定在缺省、大端、小端情况下的输出可执行文件格式,这里都指定输出格式是elf32,小端和arm体系结构。

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

 

OUTPUT_ARCH(arm)

/*  指定可执行映像文件的起始段的段名是_start */

ENTRY(_start)

SECTIONS

{

/* 指定可执行image文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置。必须使编译器知道这个地址,通常都是修改此处来完成 */

       . = 0x00000000;   /* 起始地址为0x00000000  */

 

;地址进行4字节对齐调整。

       . = ALIGN(4);

       .text :

       {

/*  代码段第一部分代码*/

              cpu/arm920t/start.o     (.text)

/*  代码段第二部分,这段由自己添加,由于在编译连接时发现,lowlevel_init.o代码段总是被连接在4kB之后,导致start.s执行到该段代码时,总是无法找到这段代码(注明:从nandflash启动才会存在这个问题)。*/

              board/samsung/smdk2410/lowlevel_init.o(.text)

              board/samsung/smdk2410/nand_read.o(.text)

/*其余代码段*/

              *(.text)

       }

 

       . = ALIGN(4);

/*  只读数据段 ,所有的只读数据段都放在这个位置*/

       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }

 

       . = ALIGN(4);

/* 可读写数据段,所有的可读写数据段都放在这里 */

       .data : { *(.data) }

 

       . = ALIGN(4);

/*指定got, got段式是uboot自定义的一个段非标准段*/

       .got : { *(.got) }

 

       . = .;

       __u_boot_cmd_start = .; /*__u_boot_cmd_start赋值为当前位置即起始位置*/
    .u_boot_cmd : { *(.u_boot_cmd) }  /*  u_boot_cmd
段,所有的u-boot命令相关的定义都放在这个位置,因为每个命令定义等长,所以只要以__u_boot_cmd_start为起始地址 进行查找就可以很快查找到某一个命令的定义,并依据定义的命令指针调用相应的函数进行处理用户的任务
*/
    __u_boot_cmd_end = .;     /* u_boot_cmd
段结束位置,由此可以看出,这段空间的长度并没有严格限制,用户可以添加一些u-boot的命令,最终都会在连接是存放在这个位置。*/   . = ALIGN(4);

 

/*__bss_start赋值为当前位置,bss段的开始位置*/

       __bss_start = .;

/*指定bss段,这里NOLOAD的意思是这段不需装载,仅在执行域中才会有这段*/

       .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }

/*_end赋值为当前位置,bss段的结束位置*/

       _end = .;

}

 

说明1:标准应用程序包括 类标准段空间:.text 运行代段;.data 全局变量等具有初始值的数据空间;.bss暂态变量,堆栈等数据空间;

说明 2.rodata.got.u_boot_cmd 等段空间由程序员设计需要而自行定义的段空间;

 

 

/board/samsung/smdk2410/config.mk 文件中定义了

#

# SMDK2410 has 1 bank of 64 MB DRAM

#

# 3000'0000 to 3400'0000

#

# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000

# optionally with a ramdisk at 3080'0000

#

# we load ourself to 33F8'0000

#

# download area is 3300'0000

#

 

 

TEXT_BASE = 0x33F80000

 

在顶层配置文件config.mk154定义了CPPFLAGS 变量,其中指定了程序的链接基址为      TEXT_BASE

    CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) -D__KERNEL__

    ifneq ($(TEXT_BASE),)

    CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)

    Endif

 

 

下面翻译下:

#SMDK2410 每个bank 64 MB DRAM

3000'00003400'0000

Linux的内核,预计将在3000'8000,进入3000'8000
#选择一个虚拟磁盘时
3080'0000

#我们载入我们自己来33F8'0000

#下载区3300'0000

下面再来看下编译连接后的的system.map文件

33f80000 T _start   //看到了吧,这就是链接基地址,由编译器指定的TEXT_BASE

33f80000 t $a

33f80020 t $d

33f80020 t _undefined_instruction

33f80024 t _software_interrupt

33f80028 t _prefetch_abort

33f8002c t _data_abort

33f80030 t _not_used

33f80034 t _irq

33f80038 t _fiq

33f80040 t _TEXT_BASE

33f80044 T _armboot_start

33f80048 T _bss_start

33f8004c T _bss_end

33f80050 t $a

33f80050 t start_code

33f800b8 t relocate

33f800d8 t copy_loop

33f800ec t nand_boot