zoukankan      html  css  js  c++  java
  • 六、u-boot 启动流程---u-boot.lds

    6.1 u-boot.lds  链接脚本分析

      uboot 编译出来的第一个链接脚本就是执行 u-boot.lds 链接脚本,去掉里面无用的和没有定义的,进行分析。

      1 /* 配置头文件,自动生成的,包含芯片SOC 相关的头文件 */
      2 #include <config.h>
      3 /* 主要是做一些 32位 和64 位的适配定义 */
      4 #include <asm/psci.h>
      5 /* 输出格式为 elf32-littlearm, */
      6 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
      7 OUTPUT_ARCH(arm)    /* 输出架构为 ARM */
      8 /* 用来指定整个程序的入口地址,所谓入口地址就是整个程序的开头地址,可以认为就是整个程序的第一句指令。有点像C语言中的main。 */
      9 ENTRY(_start)        /* _start 就是汇编的起始函数 */
     10 /* SECTIONS 就是整个链接脚本的指定 */
     11 SECTIONS
     12 {
     13     /*  指定程序的链接地址有2种方法:一种是在Makefile中ld的flags用-Ttext 0x20000000来指定;
     14         第二种是在链接脚本的SECTIONS开头用.=0x20000000来指定。
     15         两种都可以实现相同效果。这两种技巧是可以共同配合使用的,也就是说既在链接脚本中指定也在ld flags中用-Ttext来指定。两个都指定以后以-Ttext指定的为准。
     16         uboot的最终链接起始地址就是在Makefile中用-Ttext 来指定的,注意 TEXT_BASE 变量。最终来源是 Makefile 中配置对应的命令中,在make xxx_config时得到的。
     17         若没有配置,则由此处指定*/
     18     . = 0x00000000;
     19 
     20     . = ALIGN(4);    /* 4字节对齐 */
     21     
     22     /* 代码段 */
     23     /* 在代码段中,必须注意文件的排列顺序,这些顺序会影响编译的时候这些 .o 文件在生成的u-boot.bin 中的排列顺序 */
     24     /* 指定必须放在前面部分的那些文件就是那些必须安排在前4KB内的文件,这些文件中的函数在前4KB会被调用。在后面第二部分(4KB之后)中调用的程序,前后顺序就无所谓了。 */
     25     .text :
     26     {
     27         /* 映像文件赋值起始地址,它在文件 arch/arm/lib/sections.c 中定义:
     28         * char __image_copy_start[0] __attribute__((section(".__image_copy_start")));*/
     29         *(.__image_copy_start)
     30         /* arch/arm/lib/vectors.S 里有一句:.section ".vectors"  */
     31         /* 这里的 vectors 是让 vector.S 链接的二进制文件的开头部分 */
     32         *(.vectors)
     33         CPUDIR/start.o (.text*)        /* 执行 start.S */
     34         *(.text*)    /* 其他代码 */
     35     }
     36 
     37     . = ALIGN(4);
     38     .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }    /* 只读数据段 */
     39 
     40     . = ALIGN(4);
     41     .data : {            /* 普通数据段,即可读写数据段 */
     42         *(.data*)
     43     }
     44 
     45     . = ALIGN(4);
     46 
     47     . = .;
     48 
     49     /* 在u-boot的linker_list.h中通过宏定义,让编译器在编译阶段生成了一些顺序链表.u_boot_list*,链接阶段顺序存放到这个.u_boot_list节中。 */
     50     /* u-boot启动过程中,会从这个节读取模块驱动,命令行支持的命令等。 */
     51     . = ALIGN(4);
     52     .u_boot_list : {
     53         KEEP(*(SORT(.u_boot_list*)));
     54     }
     55 
     56     . = ALIGN(4);
     57     
     58     /* UEFI 段 */
     59     .__efi_runtime_start : {
     60         *(.__efi_runtime_start)
     61     }
     62 
     63     .efi_runtime : {
     64         *(efi_runtime_text)
     65         *(efi_runtime_data)
     66     }
     67 
     68     .__efi_runtime_stop : {
     69         *(.__efi_runtime_stop)
     70     }
     71 
     72     .efi_runtime_rel_start :
     73     {
     74         *(.__efi_runtime_rel_start)
     75     }
     76 
     77     .efi_runtime_rel : {
     78         *(.relefi_runtime_text)
     79         *(.relefi_runtime_data)
     80     }
     81 
     82     .efi_runtime_rel_stop :
     83     {
     84         *(.__efi_runtime_rel_stop)
     85     }
     86     /* UEFI 段结束地方 */
     87     
     88     . = ALIGN(4);
     89 
     90     .image_copy_end :
     91     {
     92         *(.__image_copy_end)
     93     }
     94 
     95     /* .rel_dyn* 段 */
     96     /* .rel_dyn_start,.rel.dyn和.rel_dyn_end提供了程序的重定位支持 */
     97     /* 重定位:
     98         在老的uboot中,如果我们想要uboot启动后把自己拷贝到内存中的某个地方,只要把要拷贝的地址写给TEXT_BASE即可,
     99         然后boot启动后就会把自己拷贝到TEXT_BASE内的地址处运行,在拷贝之前的代码都是相对的,不能出现绝对的跳转,否则会跑飞。
    100         在新版的uboot里,TEXT_BASE的含义改变了。它表示用户要把这段代码加载到哪里,通常是通过串口等工具。
    101         然后搬移的时候由uboot自己计算一个地址来进行搬移。
    102         新版的uboot采用了动态链接技术,在lds文件中有__rel_dyn_start和__rel_dyn_end,这两个符号之间的区域存放着动态链接符号,
    103         只要给这里面的符号加上一定的偏移,拷贝到内存中代码的后面相应的位置处,就可以在绝对跳转中找到正确的函数。*/
    104     .rel_dyn_start :
    105     {
    106         *(.__rel_dyn_start)
    107     }
    108 
    109     .rel.dyn : {
    110         *(.rel*)
    111     }
    112 
    113     .rel_dyn_end :
    114     {
    115         *(.__rel_dyn_end)
    116     }
    117 
    118     .end :
    119     {
    120         *(.__end)
    121     }
    122 
    123     _image_binary_end = .;
    124 
    125     /*
    126      * Deprecated: this MMU section is used by pxa at present but
    127      * should not be used by new boards/CPUs.
    128      */
    129      /* MMU 表项 */
    130     . = ALIGN(4096);
    131     .mmutable : {
    132         *(.mmutable)
    133     }
    134 
    135 /*
    136  * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
    137  * __bss_base and __bss_limit are for linker only (overlay ordering)
    138  */
    139     /* bss 段,.bss节包含了程序中所有未初始化的全局变量 */
    140     /* 由链接指令(OVERLAY)可见,.bss_start与__rel_dyn_start,.bss与__bss_base,.bss_end与__bss_limit是重叠的。*/
    141     .bss_start __rel_dyn_start (OVERLAY) : {
    142         KEEP(*(.__bss_start));
    143         __bss_base = .;
    144     }
    145 
    146     .bss __bss_base (OVERLAY) : {
    147         *(.bss*)
    148          . = ALIGN(4);
    149          __bss_limit = .;
    150     }
    151 
    152     .bss_end __bss_limit (OVERLAY) : {
    153         KEEP(*(.__bss_end));
    154     }
    155 
    156     /* 其他段,这些节都是在编译链接时自动生成的,主要用于动态链接或调试使用: */
    157     .dynsym _image_binary_end : { *(.dynsym) }    /* 动态符号表`dynamic symbol`,但与`.symtab`不同,`.dynsym`只保存动态链接相关的符号,而`.symtab`通常保存了所有的符号; */
    158     .dynbss : { *(.dynbss) }    /* 动态未初始化数据表`dynamic bss`; */
    159     .dynstr : { *(.dynstr*) }    /* 动态字符串表`dynamic string`,用于保存符号名的字符串表; */
    160     .dynamic : { *(.dynamic*) }    /* 保存了动态链接所需要的基本信息,例如依赖哪些共享对象,动态链接符号表的位置,动态链接重定位表的位置,共享对象初始化代码的地址等; */
    161     .plt : { *(.plt*) }            /* 程序连接表`Procddure Linkage Table`,是实现动态链接的必要数据; */
    162     .interp : { *(.interp*) }    /* 解释器`interpreter`的缩写 */
    163     .gnu.hash : { *(.gnu.hash) }    
    164     .gnu : { *(.gnu*) }
    165     .ARM.exidx : { *(.ARM.exidx*) }    
    166     .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
    167     /*.gnu.hash .gnu .ARM.exidx`和`.gnu.linkonce.armexidx`是针对`arm`体系专门生成的段,用于调试时函数调用的`backtrace`,如果不需要调试,则可以不用这两段。 */
    168 }

    6.2 其他

      在 u-boot 的编译过程中会生成 3 个符号表文件:

    • u-boot.map
    • u-boot.sym
    • System.map

      可以通过查看 .uboot.cmd 显示 uboot 编译链接的数据:

     1 cmd_u-boot := arm-linux-ld.bfd   -pie  --gc-sections -Bstatic  --no-dynamic-linker -Ttext 0x0 -o u-boot 
     2             -T u-boot.lds arch/arm/cpu/arm920t/start.o --start-group  
     3             arch/arm/cpu/built-in.o  
     4             arch/arm/cpu/arm920t/built-in.o  
     5             arch/arm/lib/built-in.o  
     6             board/samsung/common/built-in.o  
     7             board/samsung/jz2440/built-in.o  
     8             cmd/built-in.o  common/built-in.o  
     9             disk/built-in.o  drivers/built-in.o  
    10             drivers/dma/built-in.o  
    11             drivers/gpio/built-in.o  
    12             drivers/i2c/built-in.o  
    13             drivers/mtd/built-in.o  
    14             drivers/mtd/nand/built-in.o  
    15             drivers/mtd/onenand/built-in.o  
    16             drivers/mtd/spi/built-in.o  
    17             drivers/net/built-in.o  
    18             drivers/net/phy/built-in.o  
    19             drivers/pci/built-in.o  
    20             drivers/power/built-in.o  
    21             drivers/power/battery/built-in.o  
    22             drivers/power/domain/built-in.o  
    23             drivers/power/fuel_gauge/built-in.o  
    24             drivers/power/mfd/built-in.o  
    25             drivers/power/pmic/built-in.o  
    26             drivers/power/regulator/built-in.o  
    27             drivers/serial/built-in.o  
    28             drivers/spi/built-in.o  
    29             drivers/usb/common/built-in.o  
    30             drivers/usb/dwc3/built-in.o  
    31             drivers/usb/emul/built-in.o  
    32             drivers/usb/eth/built-in.o  
    33             drivers/usb/gadget/built-in.o  
    34             drivers/usb/gadget/udc/built-in.o  
    35             drivers/usb/host/built-in.o  
    36             drivers/usb/musb-new/built-in.o  
    37             drivers/usb/musb/built-in.o  
    38             drivers/usb/phy/built-in.o  
    39             drivers/usb/ulpi/built-in.o  
    40             env/built-in.o  
    41             fs/built-in.o  
    42             lib/built-in.o  
    43             net/built-in.o  
    44             test/built-in.o  
    45             test/dm/built-in.o 
    46             --end-group arch/arm/lib/eabi_compat.o  arch/arm/lib/lib.a -Map u-boot.map;
    47             true

      -pic-pie ,一个用于动态库的位置无关,一个用于动态可执行文件的位置无关。

      -Ttext 用于指定指定链接的起始地址

      -T u-boot.lds指定了链接使用的脚本文件,实际上,在这个脚本文件的.text节开始前同样也指定了起始地址:

      

  • 相关阅读:
    PHP的垃圾回收机制
    python使用httpHandler处理请求案例
    使用python中urllib.request.Request()来构建ua
    Pillow《转载》
    python数据格式化之pprint
    使用Mechanize实现自动化表单处理
    beautifulSoup《转》
    Python3网络爬虫(四):使用User Agent和代理IP隐藏身份《转》
    python urllib和urllib3包使用
    使用Mechanize实现自动化表单处理
  • 原文地址:https://www.cnblogs.com/kele-dad/p/8985225.html
Copyright © 2011-2022 走看看