uboot-链接脚本(u-boot.lds)

学习目标:

uboot链接脚本分析

学习内容:

学习使用了正点原子的I.MX6ULL教程及开发平台。
uboot的链接脚本u-boot.lds,u-boot.map。

学习时间:

2022-07-17

学习产出:

分析uboot的启动流程之前,首先要找到uboot的入口函数,第一个运行的函数在哪里。uboot编译完之后都是需要通过链接脚本来指定程序如何存放。所以可以通过链接脚本找到uboot的入口函数。
uboot在编译完成后会在uboot的根目录下生成一个名为uboot.lds的链接脚本文件,此文件是根据arch/arm/cpu/u-boot.lds文件,经过uboot编译后生成的,uboot在编译时,会根据原本的链接脚本文件增加一些东西,才最终在uboot的根目录下生成u-boot.lds最终使用的链接脚本文件。在uboot编译时,会打印如下链接命令:

  arm-linux-gnueabihf-ld.bfd   -pie  --gc-sections -Bstatic 
  -Ttext 0x87800000 -o u-boot -T u-boot.lds 
  arch/arm/cpu/armv7/start.o --start-group  
   arch/arm/cpu/built-in.o  
   arch/arm/cpu/armv7/built-in.o
   arch/arm/imx-common/built-in.o  
   arch/arm/lib/built-in.o 
   board/freescale/common/built-in.o  
   board/freescale/mx6ullevk/built-in.o  
   cmd/built-in.o  
   common/built-in.o
   disk/built-in.o  
   drivers/built-in.o  
   drivers/dma/built-in.o 
   drivers/gpio/built-in.o  
   drivers/i2c/built-in.o  
   drivers/mmc/built-in.o  
   drivers/mtd/built-in.o  
   drivers/mtd/onenand/built-in.o  
   drivers/mtd/spi/built-in.o 
   drivers/net/built-in.o  
   drivers/net/phy/built-in.o  
   drivers/pci/built-in.o  
   drivers/power/built-in.o  
   drivers/power/battery/built-in.o  
   drivers/power/fuel_gauge/built-in.o 
   drivers/power/mfd/built-in.o 
   drivers/power/pmic/built-in.o 
   drivers/power/regulator/built-in.o 
   drivers/serial/built-in.o  
   drivers/spi/built-in.o 
   drivers/usb/dwc3/built-in.o  
   drivers/usb/emul/built-in.o  
   drivers/usb/eth/built-in.o  
   drivers/usb/gadget/built-in.o
   drivers/usb/gadget/udc/built-in.o 
   drivers/usb/host/built-in.o  
   drivers/usb/musb-new/built-in.o  
   drivers/usb/musb/built-in.o  
   drivers/usb/phy/built-in.o  
   drivers/usb/ulpi/built-in.o  
   fs/built-in.o  
   lib/built-in.o  
   net/built-in.o  
   test/built-in.o  
   test/dm/built-in.o 
   --end-group arch/arm/lib/eabi_compat.o  
   -L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4 -lgcc -Map u-boot.map

这些就是根据链接脚本u-boot.lds执行链接的过程,由此可知链接地址为0x87800000。
uboot根目录中链接脚本的内容如下:

#指定输出可执行文件是elf格式,32位ARM指令,小端模式
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)#指定输出而执行文件运行于ARM平台
ENTRY(_start)#程序默认的入口函数为_start
SECTIONS
{
 . = 0x00000000;#指明目标代码起始地址为0x0,"."代表当前位置
 . = ALIGN(4);#按4字节对齐
 .text :#.text代码段,可读可执行
 {
  *(.__image_copy_start)#uboot映像文件复制起始地址,在u-boot.map中定义
  *(.vectors)#中断向量表
  arch/arm/cpu/armv7/start.o (.text*)#start.o文件
  *(.text*)#其他代码段
 }
 . = ALIGN(4);
 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }#只读数据段RO段(存放常量)
 . = ALIGN(4);
 .data : {#读写数据段 RW段(存放已经初始化的全局变量和静态变量)
  *(.data*)
 }
 . = ALIGN(4);
 . = .;
 . = ALIGN(4);
 .u_boot_list : {#uboot.list段
  KEEP(*(SORT(.u_boot_list*)));
 }
 . = ALIGN(4);
 .image_copy_end :#uboot映像文件复制结束地址,在u-boot.map中定义
 {
  *(.__image_copy_end)
 }
 .rel_dyn_start :
 {
  *(.__rel_dyn_start)
 }
 .rel.dyn : {
  *(.rel*)
 }
 .rel_dyn_end :
 {
  *(.__rel_dyn_end)
 }
 .end :
 {
  *(.__end)
 }
 _image_binary_end = .;
 . = ALIGN(4096);
 .mmutable : {
  *(.mmutable)
 }
 .bss_start __rel_dyn_start (OVERLAY) : {#bss段起始地址
  KEEP(*(.__bss_start));
  __bss_base = .;
 }
 .bss __bss_base (OVERLAY) : {
  *(.bss*)
   . = ALIGN(4);
   __bss_limit = .;
 }
 .bss_end __bss_limit (OVERLAY) : {#bss段结束地址
  KEEP(*(.__bss_end));
 }
 .dynsym _image_binary_end : { *(.dynsym) }
 .dynbss : { *(.dynbss) }
 .dynstr : { *(.dynstr*) }
 .dynamic : { *(.dynamic*) }
 .plt : { *(.plt*) }
 .interp : { *(.interp*) }
 .gnu.hash : { *(.gnu.hash) }
 .gnu : { *(.gnu*) }
 .ARM.exidx : { *(.ARM.exidx*) }
 .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}

uboot.map文件是uboot的映射文件,从此文件中可以看出某个文件或者函数被链接到了哪个地址,文件部分内容如下:

名称           来源             长度             属性
*default*        0x0000000000000000 0xffffffffffffffff

链结器命令稿和内存映射

段 .text 的地址设置为 0x87800000
                0x0000000000000000                . = 0x0
                0x0000000000000000                . = ALIGN (0x4)

.text           0x0000000087800000    0x3f93c
 *(.__image_copy_start)
 .__image_copy_start
                0x0000000087800000        0x0 arch/arm/lib/built-in.o
                0x0000000087800000                __image_copy_start
 *(.vectors)
 .vectors       0x0000000087800000      0x300 arch/arm/lib/built-in.o
                0x0000000087800000                _start
                0x0000000087800020                _undefined_instruction
                0x0000000087800024                _software_interrupt
                0x0000000087800028                _prefetch_abort
                0x000000008780002c                _data_abort
                0x0000000087800030                _not_used
                0x0000000087800034                _irq
                0x0000000087800038                _fiq
                0x0000000087800040                IRQ_STACK_START_IN
 arch/arm/cpu/armv7/start.o(.text*)
 .text          0x0000000087800300       0xb0 arch/arm/cpu/armv7/start.o
                0x0000000087800300                reset
                0x0000000087800304                save_boot_params_ret
                0x0000000087800340                c_runtime_cpu_setup
                0x0000000087800350                save_boot_params
                0x0000000087800354                cpu_init_cp15
                0x00000000878003a8                cpu_init_crit
 *(.text*)
 .text          0x00000000878003b0       0x24 arch/arm/cpu/armv7/built-in.o
                0x00000000878003b0                lowlevel_init
 .text.v7_maint_dcache_all
                0x00000000878003d4       0xcc arch/arm/cpu/armv7/built-in.o
 .text.invalidate_icache_all
                0x00000000878004a0       0x18 arch/arm/cpu/armv7/built-in.o
                0x00000000878004a0                invalidate_icache_all
 .text.v7_outer_cache_enable
                0x00000000878004b8        0x4 arch/arm/cpu/armv7/built-in.o
                0x00000000878004b8                v7_outer_cache_enable
 .text.v7_outer_cache_disable
                0x00000000878004bc        0x4 arch/arm/cpu/armv7/built-in.o
                0x00000000878004bc                v7_outer_cache_disable
 .text.v7_outer_cache_flush_all
                0x00000000878004c0        0x4 arch/arm/cpu/armv7/built-in.o
                0x00000000878004c0                v7_outer_cache_flush_all
 .text.flush_dcache_all
                0x00000000878004c4       0x14 arch/arm/cpu/armv7/built-in.o
                0x00000000878004c4                flush_dcache_all

从中可以看出__image_copy_start的地址为0x87800000,入口函数_start位于文件arch/arm/lib/vectors.S文件中,此文件内容如下:

#include <config.h>
.globl _start
	.section ".vectors", "ax"
_start:

#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
	.word	CONFIG_SYS_DV_NOR_BOOT_CFG
#endif

	b	reset
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq

_start 后面就是中断向量表,从图中的“.section “.vectors”,"ax”可以得到,此代码存放在.vectors 段里面。
从u-boot.map文件中可以看出一些变量值,如下:

__image_copy_start	0x87800000	uboot 拷贝的首地址
__image_copy_end	0x87853728	uboot 拷贝的结束地址
__rel_dyn_start		0x87853728	.rel.dyn 段起始地址
__rel_dyn_end		0x8785c3c8	.rel.dyn 段结束地址
image_binary_end	0x8785c3c8	镜像结束地址
__bss_start			0x87853728	.bss 段起始地址
__bss_end			0x8789e814	.bss 段结束地址

除了__image_copy_start以外,其他的变量值每次编译的时候可能会变化,如果修改了 uboot 代码、修改了 uboot 配置、选用不同的优化等级等等都会影响到这些值。所以,一切以实际值为准!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值