u-boot(四)-顶层目录链接脚本文件(u-boot.lds)介绍

2024-06-14 09:28

本文主要是介绍u-boot(四)-顶层目录链接脚本文件(u-boot.lds)介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一,IMX6ULL映像文件

1,格式概述

对于IMX6ULL,烧写在EMMC、SD/TF卡上的程序,并不能“自己复制自己”,是“别人把它复制到内存里”。一上电首先运行的是boot ROM上的程序,它从EMMC、SD/TF卡上把程序复制进内存里。

烧写在EMMC、SD卡或是TF卡上的,除了程序本身,还有位置信息、DCD 信息,这些内容合并成一个映像文件,如下图:

这4 部分内容合并成为一个映像文件,烧写在EMMC、SD 卡或TF 卡等启动设备的某个固定地址,boot ROM 程序去这个固定地址读出映像文件。启动设备不同, 固定地址不同,如下图:

 

2,格式详解

下面的讲解图中,列有C 语言格式的结构体,这些结构体来源于U-boot 的tools 目录下的imximage.h。

2.1 Image Vector Table(IVT)

IVT 会被放在固定的地址,IVT 中是一系列的地址,boot ROM 程序会根据这些地址来确定映像文件中其他部分在哪里。

IVT 格式如下:

要注意的是上图中这4项:

a) header:里面有3项:tag、length、version。length表示IVT的大小,它是32字节。要注意是的,它是大字节序的。

b) entry:用户程序运行时第1条指令的地址,就是程序的链接地址、程序被复制到内存哪里。

c) dcd:映像被复制到内存后,其中的DCD数据的地址。

d) boot data:映像被复制到内存后,其中的boot data的地址。

e) self:映像被复制到内存后,IVT自己所在的地址。

2.2 Boot data

映像被复制到内存后,整个映像文件(IVT之前还有几个扇区数据,比如分区表)所在的地址。

a) start:这是映像文件在内存中的地址,以SD/TF卡为例:

映像文件=(1K数据,内含分区表等信息)+IVT+BootData+DCD+用户数据(bin文件)

注意,IVT并不在映像文件的最前面,start也不是IVT在内存中的地址,而是整个映像文件在内存中的地址:

start = IVT在内存中的地址 - IVT offset

什么意思?假设IVT被保存在启动设备TF卡1024偏移地址处,IVT被复制到内存地址0x87000000,那么start=0x87000000-1024。

所以start表示的是启动设备开头的数据,被复制到内存哪里去。

从它的含义也可以推理出:boot ROM程序会把启动设备开头的数据,复制到内存;而不仅仅是从IVT开始复制。

b) length:保存在启动设备上的整个映像文件的长度,从0地址开始(不是从IVT开始)。

c) plugin:这是一个标记位,当它为1时表示这个映像文件是“plugin”,即插件。

boot ROM程序可以支持有限的启动设备,如果你想双持更多的启动设备比如网络启动、CDROM启动,就需要提供对应的驱动。这些驱动就是“plugin”,我们的教程不涉及,该标记位为0。

Boot data就是用来表示映像文件应该被复制到哪里去,以及它的大小。boot ROM程序就是根据它来把整个映像文件复制到内存去的。

2.3 DCD

“Device Configuration Data”,设备配置数据(DCD),这些DCD将会跟bin文件一起打包烧写在启动设备上。boot ROM程序会从启动设备上读出DCD数据,根据DCD来写对应的寄存器以便初始化芯片。DCD中列出的是对某些寄存器的读写操作,我们可以在DCD中设置DDR控制器的寄存器值,可以在DCD中使用更优的参数设置必需的硬件。这样boot ROM程序就会帮我们初始化DDR和其他硬件,然后才可以把bin程序读到DDR中并运行。

实际上DCD还可以更复杂,它支持多种命令:write data、check data、nop、unlock。我们可以通过write data命令写寄存器,通过check data命令等待寄存器就绪。

2.4 User code and data

就是用户程序或数据,原原本本地添加到映像文件里就可以。

3,实例

制作过程中各项值的计算方法如下图所示:

我们不需要手工去计算,一个mkimage命令就搞定了。上图中各步骤细说如下:

1)确定入口地址entry

我们的程序运行时要放在内存中哪一个位置,这是我们决定的。它被称为入口地址、链接地址。

2)确定映像文件在内存中的地址start

boot ROM程序启动时,会把“Initial Load Region”读出来,“Initial load  Region”里含有IVT、Boot data、DCD。boot ROM根据DCD初始化设备后,再把整个映像文件读到内存。

在启动设备上,“Initial Load Region”之后紧跟着我们的程序,反过来说就是我们程序的前面,放着“Initial Load Region”。假设“Initial Load Region”的大小为load_size,那么在内存中“Initial Load Region”的位置start = entry –  load_size。

注意:“Initial Load Region”位于启动设备0位置,它的头部并不是IVT,而是一些无用的数据(或是分区信息)。

在IMX6ULL中有一个表格,列出了不同启动设备对应的“Initial Load Region  Size”:

 

3)确定IVT在内存中的地址self:

我们知道IVT在启动设备上某个固定的位置,上或中的“Image Vector Table  Offset”:ivt_offset。那么在内存中它的位置可以如下计算:

self = start + ivt_offset = entry – load_size + ivt_offset

4)确定Boot data在内存中的地址boot_data

IVT的大小是32字节,IVT之后就是Boot data,而IVT中的boot_data值表示Boot  data在内存中的位置,计算如下:

boot_data = self + 32 = entry – load_size + ivt_offset + 32

5)确定DCD在内存中的地址dcd

Boot data的大小是12字节,Boot data之后就是DCD,而IVT中的dcd值表示DCD在内存中的位置,计算如下:

dcd = boot_data + 12 = entry – load_size + ivt_offset + 44

6)写入DCD的数据:

DCD是用初始化硬件的,特别是初始化DDR。而DDR的初始化非常的复杂、专业,我们一般是使用硬件厂家提供的代码。

我们是使用类似下面的指令来制作映象文件:

./tools/mkimage -n board/freescale/mx6ullevk/imximage.cfg.cfgtmp -T imximage -e 0x87800000 -d u-boot-dtb.bin u-boot-dtb.imx

上述命令中的imximage.cfg.cfgtmp就是厂家提供的,内部截取部分贴出来:

从上图也可以看到imximage.cfg.cfgtmp文件中基本是对寄存器的写操作。

mkimage程序来自u-boot,它会把imximage.cfg.cfgtmp中的内容转换为DCD数据。

7)写入用户程序

经过上述7个步骤,整个映像文件就构造出来了,可以把它烧入启动设备。

二,u-boot.lds链接脚本

1,u-boot.lds

链接脚本控制程序的链接过程,它规定如何把输入文件内的段放入输出文件, 并控制输出文件内的各部分在程序地址空间内的布局。

如果没有编译过 u-boot的话链接脚本为 arch/arm/cpu/u-boot.lds。但是这个不是最终使用的链接脚本,最终的链接脚本是在这个链接脚本的基础上生成的。编译一下 u-boot,编译完成以后就会在 uboot 根目录下生成 u-boot.lds

arm-buildroot-linux-gnueabihf-gcc -E -Wp,-MD,./.u-boot.lds.d -D__KERNEL__ -D__UBOOT__   -D__ARM__ -marm -mno-thumb-interwork  -mabi=aapcs-linux  -mword-relocations  -fno-pic  -mno-unaligned-access  -ffunction-sections -fdata-sections -fno-common-ffixed-r9  -msoft-float   -pipe  -march=armv7-a -D__LINUX_ARM_ARCH__=7   -Iinclude   -I./arch/arm/include -include ./include/linux/kconfig.h -I.  -nostdinc -isystem/home/zhuwg1/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin/../lib/gcc/arm-buildroot-linux-gnueabihf/7.5.0/include -ansi -include ./include/u-boot/u-boot.lds.h -DCPUDIR=arch/arm/cpu/armv7  -D__ASSEMBLY__ -x assembler-with-cpp -P -o u-boot.lds arch/arm/cpu/u-boot.lds

u-boot.lds:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
/*
*    首先定义了二进制程序的输出格式为"elf32-littlearm",
*    架构是"arm",程序入口为"_start"符号;
*/
ENTRY(_start)
SECTIONS
{
//定义了程序链接的基地址,默认是0,通过配置CONFIG_SYS_TEXT_BASE可修改这个默认值
. = 0x00000000;
//地址4字节对齐
. = ALIGN(4);
//代码段
.text :
{
/*
*    __image_copy_start和__image_copy_end用于定义需要重定向的段,
*    u-boot将启动初始化分为了两个部分,重定向前初始化board_f和
*    重定向后初始化board_r,在重定向之前完成一些必要初始化,
*    包括可能的ddr初始化,然后通过__image_copy_start和__image_copy_end
*    将u-boot搬运到ddr中,并在ddr中进行重定向后初始化。*(.__image_copy_start)
//vectors段, vectors 段保存中断向量表,从u-boot.lds文件我们知道了vectors.S的代码是存在vectors段中的;从地址映射文件中,vectors段的起始地址也是0X87800000,说明整个uboot的起始地址就是 0X87800000。*(.vectors)
//将 arch/arm/cpu/armv7/start.s 编译出来的代码放到中断向量表后面arch/arm/cpu/armv7/start.o (.text*)
// text段,其他的代码段就放到这里*(.text*)
}
. = ALIGN(4);
// .rodata只读数据段(一般存放常量)
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
//数据段 (一般存放已初始化的全局和静态变量)
.data : {*(.data*)
}
. = ALIGN(4);
. = .;
. = ALIGN(4);
/*
*     u_boot_list段定义了系统中当前支持的所有命令和设备驱动,此段把散落在各个文件中
*     通过U_BOOT_CMD的一系列拓展宏定义的命令和U_BOOT_DRIVER的拓展宏定义的设备驱动收集到一起,
*     并按照名字排序存放,以便后续在命令行快速检索到命令并执行和检测注册的设备和设备树匹配
*     probe设备驱动初始化;(设备驱动的probe只在定义了dm模块化驱动时有效)
*/
.u_boot_list : {KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN(4);
// 在定义了efi运行时相关支持时才会出现使用的段,一般不用关心
.__efi_runtime_start : {*(.__efi_runtime_start)
}
.efi_runtime : {*(efi_runtime_text)*(efi_runtime_data)
}
.__efi_runtime_stop : {*(.__efi_runtime_stop)
}
.efi_runtime_rel_start :
{*(.__efi_runtime_rel_start)
}
.efi_runtime_rel : {*(.relefi_runtime_text)*(.relefi_runtime_data)
}
.efi_runtime_rel_stop :
{*(.__efi_runtime_rel_stop)
}
. = ALIGN(8);
//.image_copy_end:uboot 拷贝的结束地址
.image_copy_end :
{*(.__image_copy_end)
}
/*
*     一般u-boot运行时是根据定义的基地址开始执行,如果加载地址和链接地址
*     不一致则会出现不能执行u-boot的问题。通过一个
*     配置CONFIG_POSITION_INDEPENDENT即可打开地址无关功能,
*     此选项会在链接u-boot时添加-PIE参数。此参数会在u-boot ELF文件中
*     生成rela*段,u-boot通过读取此段中表的相对地址值与实际运行时地址值
*     依次遍历进行修复当前所有需要重定向地址,使其可以实现地址无关运行;
*     即无论链接基地址如何定义,u-boot也可以在任意ram地址
*     运行(一般需要满足最低4K或者64K地址对齐);
*
*     注意此功能只能在sram上实现,因为此功能会在运行时修改文本段数据段中的地址,
*     如果此时运行在片上flash,则不能写flash,导致功能失效无法实现地址无关;
*/
.rel_dyn_start :
{*(.__rel_dyn_start)
}
.rel.dyn : {*(.rel*)
}
.rel_dyn_end :
{*(.__rel_dyn_end)
}
.end :
{*(.__end)
}
_image_binary_end = .;
. = ALIGN(4096);
.mmutable : {*(.mmutable)
}
//bbs段
.bss_start __rel_dyn_start (OVERLAY) : {KEEP(*(.__bss_start));__bss_base = .;
}
.bss __bss_base (OVERLAY) : {*(.bss*). = ALIGN(4);__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {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.*) }
}

_start 在文件 arch/arm/lib/vectors.S 中有定义,表示代码执行入口,也就是第一条指令要放的位置。注意armv7的入口在vectors.S(armv8在start.s),中断向量表放在指令入口最开始的位置:可以看到_start后面就是中断向量表,从图中的“.section ".vectors", "ax”可以得到,此代码存放在.vectors 段里面。

打开u-boot.map如下图:因此代码段的排列顺序为:先放中断向量表,也就是vectors.s,然后再放start.s相关内容,最后放其他的.text段(一大堆built-in.o)。

 

注意这里为什么uboot.map中_start入口地址为什么是0x8780,0000。 链接脚本指定了程序的运行(链接)地址:

程序链接时会指定程序的运行(链接)地址:

  arm-buildroot-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/domain/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/cdns3/built-in.o  drivers/usb/common/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  arch/arm/lib/lib.a -Map u-boot.map

运行地址0x87800000定义在:

include/configs/mx6_common.h:86:#define CONFIG_SYS_TEXT_BASE    0x87800000

2,System.map/u-boot.map

U-Boot编译之后会在其顶级目录中生成System.map和u-boot.map两个文件。

System.map用于存放符号表信息。 符号表是所有符号和其对应地址的一个列表,随着每次的编译,就会产生一个新的对应的System.map文件,当运行出错时, 通过System.map中的符号表解析,就可以查到一个地址值对应的变量名。按链接地址由小到大的顺序列出所有符号:

87800000 T __image_copy_start
87800000 T _start
87800020 T _undefined_instruction
87800024 T _software_interrupt
87800028 T _prefetch_abort
8780002c T _data_abort
87800030 T _not_used
87800034 T _irq
87800038 T _fiq
87800040 T IRQ_STACK_START_IN
87800060 t undefined_instruction
878000c0 t software_interrupt
87800120 t prefetch_abort
87800180 t data_abort
878001e0 t not_used
87800240 t irq
878002a0 t fiq
878002e8 T reset
878002ec T save_boot_params_ret
87800328 T c_runtime_cpu_setup
87800338 W save_boot_params
8780033c T cpu_init_cp15
87800390 T cpu_init_crit
87800398 T __v7_flush_dcache_all
878003ac t start_flush_levels
878003b0 t flush_levels

由上面信息可知,_start 符号被链接在最前面的地址0x87800000,它是U-Boot的入口。SDRAM初始化完成后,需要将U-Boot加载到上述地址。

u-boot.map中包含了链接过程中涉及的目标文件和所依赖的库文件,然后所链接的目标文件的先后顺序并列出各目标文件中各符号所链接的地址。

Memory Configuration
Name             Origin             Length             Attributes
*default*        0x0000000000000000 0xffffffffffffffff
Linker script and memory map
Address of section .text set to 0x87800000
0x0000000000000000                . = 0x0
0x0000000000000000                . = ALIGN (0x4)
//代码段
.text           0x0000000087800000    0x499f0
*(.__image_copy_start)
.__image_copy_start
0x0000000087800000        0x0 arch/arm/lib/built-in.o
0x0000000087800000                __image_copy_start
*(.vectors)
//中断向量表
.vectors       0x0000000087800000      0x2e8 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*)
//arch/arm/cpu/armv7/start.o
.text          0x00000000878002e8       0xb0 arch/arm/cpu/armv7/start.o
0x00000000878002e8                reset
0x00000000878002ec                save_boot_params_ret
0x0000000087800328                c_runtime_cpu_setup
0x0000000087800338                save_boot_params
0x000000008780033c                cpu_init_cp15
0x0000000087800390                cpu_init_crit
//其它代码段
*(.text*)
.text          0x0000000087800398      0x16c arch/arm/cpu/armv7/built-in.o
0x0000000087800398                __v7_flush_dcache_all
0x000000008780042c                v7_flush_dcache_all
0x000000008780043c                __v7_invalidate_dcache_all
0x00000000878004d0                v7_invalidate_dcache_all
0x00000000878004e0                lowlevel_init
.text.invalidate_icache_all
0x0000000087800504       0x18 arch/arm/cpu/armv7/built-in.o
0x0000000087800504                invalidate_icache_all
... ...
.rodata         0x00000000878499f0    0x11d08
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
.rodata.efi_boot_services
0x00000000878499f0       0xc8 lib/built-in.o
.rodata.lcd_pads
0x0000000087849ab8       0xf0 board/freescale/mx6ullevk/built-in.o
.rodata.uart1_pads
0x0000000087849ba8       0x10 board/freescale/mx6ullevk/built-in.o
.rodata        0x0000000087849bb8       0x80 arch/arm/lib/built-in.o
.rodata        0x0000000087849c38        0x8 drivers/mmc/built-in.o
.rodata.CSWTCH.11
0x0000000087849c40       0xc8 arch/arm/imx-common/built-in.o
.rodata.CSWTCH.32
0x0000000087849d08       0x20 common/built-in.o
.rodata.CSWTCH.38
0x0000000087849d28       0x20 disk/built-in.o
.rodata.CSWTCH.57
0x0000000087849d48       0x14 cmd/built-in.o
.rodata.asix_eth_id_table
0x0000000087849d5c      0x138 drivers/usb/eth/built-in.o
.rodata.asix_eth_ops
... ...
.data           0x000000008785b710     0xec04
*(.data*)
.data.rel.ro   0x000000008785b710        0x0 arch/arm/cpu/armv7/start.o
.data.imx_ccm  0x000000008785b710        0x4 arch/arm/cpu/armv7/built-in.o
0x000000008785b710                imx_ccm
.data.base     0x000000008785b714        0x4 arch/arm/imx-common/built-in.o
.data.reset_cause
0x000000008785b718        0x4 arch/arm/imx-common/built-in.o
.data.display_count
0x000000008785b71c        0x4 board/freescale/mx6ullevk/built-in.o
0x000000008785b71c                display_count
.data.bootm_help_text
... ...
.u_boot_list    0x000000008786a320     0x1580
*(SORT_BY_NAME(.u_boot_list*))
.u_boot_list_2_blk_driver_1
0x000000008786a320        0x0 drivers/built-in.o
.u_boot_list_2_blk_driver_2_mmc
0x000000008786a320       0x18 drivers/mmc/built-in.o
0x000000008786a320                _u_boot_list_2_blk_driver_2_mmc
.u_boot_list_2_blk_driver_2_usb
0x000000008786a338       0x18 common/built-in.o
0x000000008786a338                _u_boot_list_2_blk_driver_2_usb
.u_boot_list_2_blk_driver_3
0x000000008786a350        0x0 drivers/built-in.o
.u_boot_list_2_cmd_1
0x000000008786a350        0x0 cmd/built-in.o
.u_boot_list_2_cmd_1
0x000000008786a350        0x0 common/built-in.o
.u_boot_list_2_cmd_2_base
0x000000008786a350       0x1c cmd/built-in.o
0x000000008786a350                _u_boot_list_2_cmd_2_base
.u_boot_list_2_cmd_2_bdinfo
0x000000008786a36c       0x1c cmd/built-in.o
0x000000008786a36c                _u_boot_list_2_cmd_2_bdinfo
... ...
.__efi_runtime_start
0x000000008786b8a0        0x0
*(.__efi_runtime_start)
.__efi_runtime_start
0x000000008786b8a0        0x0 arch/arm/lib/built-in.o
.efi_runtime    0x000000008786b8a0      0x100
*(efi_runtime_text)
efi_runtime_text
0x000000008786b8a0       0x24 lib/built-in.o
0x000000008786b8a0                efi_reset_system
0x000000008786b8a4                efi_get_time
*(efi_runtime_data)
*fill*         0x000000008786b8c4        0x4
... ...
.image_copy_end
0x000000008786ba30        0x0
*(.__image_copy_end)
.__image_copy_end
0x000000008786ba30        0x0 arch/arm/lib/built-in.o
... ...
.rel_dyn_start  0x000000008786ba30        0x0
*(.__rel_dyn_start)
.__rel_dyn_start
0x000000008786ba30        0x0 arch/arm/lib/built-in.o
.rel.dyn        0x000000008786ba30     0xa538
*(.rel*)
.rel.got       0x000000008786ba30        0x0 arch/arm/cpu/armv7/start.o
... ...
.rel_dyn_end    0x0000000087875f68        0x0
*(.__rel_dyn_end)
.__rel_dyn_end
0x0000000087875f68        0x0 arch/arm/lib/built-in.o
.end            0x0000000087875f68        0x0
*(.__end)
.__end         0x0000000087875f68        0x0 arch/arm/lib/built-in.o
0x0000000087875f68                _image_binary_end = .
0x0000000087876000                . = ALIGN (0x1000)
... ...
.bss_start      0x000000008786ba30        0x0
*(.__bss_start)
.__bss_start   0x000000008786ba30        0x0 arch/arm/lib/built-in.o
0x000000008786ba30                __bss_start
0x000000008786ba30                __bss_base = .
.bss            0x000000008786ba30    0x37f00
*(.bss*)
.bss.modes     0x000000008786ba30        0x8 arch/arm/imx-common/built-in.o
.bss.params    0x000000008786ba38        0x4 arch/arm/lib/built-in.o
... ...
.bss_end        0x00000000878a3930        0x0
*(.__bss_end)
.__bss_end     0x00000000878a3930        0x0 arch/arm/lib/built-in.o
0x00000000878a3930                __bss_end

 可以从u-boot.map获取下面符号的地址:

变量   

数值 

描述

*(.vectors)

0x87800000

中断向量表

arch/arm/cpu/armv7/start.o 

0x87800300 

start.c

__image_copy_start 

0x87800000

 u-boot拷贝的首地址

__image_copy_end

0x8785dd54

u-boot拷贝的结束地址

.rodata

0x878499f0

只读数据段

.data

0x8785b710 

数据段

__rel_dyn_start

 0x8785dd54

 .rel.dyn 段起始地址

__rel_dyn_end

 0x878668f4 

.rel.dyn 段结束地址

_image_binary_end

0x878668f4

镜像结束地址

__bss_start    

0x8785dd54

.bss 段起始地址

__bss_end

 0x878a8e74

 .bss 段结束地址

 

参考链接:

https://www.cnblogs.com/fuzidage/p/17901516.html

这篇关于u-boot(四)-顶层目录链接脚本文件(u-boot.lds)介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1060010

相关文章

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

Spring Boot整合log4j2日志配置的详细教程

《SpringBoot整合log4j2日志配置的详细教程》:本文主要介绍SpringBoot项目中整合Log4j2日志框架的步骤和配置,包括常用日志框架的比较、配置参数介绍、Log4j2配置详解... 目录前言一、常用日志框架二、配置参数介绍1. 日志级别2. 输出形式3. 日志格式3.1 PatternL

如何使用Spring boot的@Transactional进行事务管理

《如何使用Springboot的@Transactional进行事务管理》这篇文章介绍了SpringBoot中使用@Transactional注解进行声明式事务管理的详细信息,包括基本用法、核心配置... 目录一、前置条件二、基本用法1. 在方法上添加注解2. 在类上添加注解三、核心配置参数1. 传播行为(

Spring Boot Actuator使用说明

《SpringBootActuator使用说明》SpringBootActuator是一个用于监控和管理SpringBoot应用程序的强大工具,通过引入依赖并配置,可以启用默认的监控接口,... 目录项目里引入下面这个依赖使用场景总结说明:本文介绍Spring Boot Actuator的使用,关于Spri

10个Python自动化办公的脚本分享

《10个Python自动化办公的脚本分享》在日常办公中,我们常常会被繁琐、重复的任务占据大量时间,本文为大家分享了10个实用的Python自动化办公案例及源码,希望对大家有所帮助... 目录1. 批量处理 Excel 文件2. 自动发送邮件3. 批量重命名文件4. 数据清洗5. 生成 PPT6. 自动化测试

使用Java实现一个解析CURL脚本小工具

《使用Java实现一个解析CURL脚本小工具》文章介绍了如何使用Java实现一个解析CURL脚本的工具,该工具可以将CURL脚本中的Header解析为KVMap结构,获取URL路径、请求类型,解析UR... 目录使用示例实现原理具体实现CurlParserUtilCurlEntityICurlHandler

10个Python Excel自动化脚本分享

《10个PythonExcel自动化脚本分享》在数据处理和分析的过程中,Excel文件是我们日常工作中常见的格式,本文将分享10个实用的Excel自动化脚本,希望可以帮助大家更轻松地掌握这些技能... 目录1. Excel单元格批量填充2. 设置行高与列宽3. 根据条件删除行4. 创建新的Excel工作表5

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed

Spring Boot统一异常拦截实践指南(最新推荐)

《SpringBoot统一异常拦截实践指南(最新推荐)》本文介绍了SpringBoot中统一异常处理的重要性及实现方案,包括使用`@ControllerAdvice`和`@ExceptionHand... 目录Spring Boot统一异常拦截实践指南一、为什么需要统一异常处理二、核心实现方案1. 基础组件