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 + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

Spring Boot结成MyBatis-Plus最全配置指南

《SpringBoot结成MyBatis-Plus最全配置指南》本文主要介绍了SpringBoot结成MyBatis-Plus最全配置指南,包括依赖引入、配置数据源、Mapper扫描、基本CRUD操... 目录前言详细操作一.创建项目并引入相关依赖二.配置数据源信息三.编写相关代码查zsRArly询数据库数

一文详解如何从零构建Spring Boot Starter并实现整合

《一文详解如何从零构建SpringBootStarter并实现整合》SpringBoot是一个开源的Java基础框架,用于创建独立、生产级的基于Spring框架的应用程序,:本文主要介绍如何从... 目录一、Spring Boot Starter的核心价值二、Starter项目创建全流程2.1 项目初始化(

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

Linux修改pip临时目录方法的详解

《Linux修改pip临时目录方法的详解》在Linux系统中,pip在安装Python包时会使用临时目录(TMPDIR),但默认的临时目录可能会受到存储空间不足或权限问题的影响,所以本文将详细介绍如何... 目录引言一、为什么要修改 pip 的临时目录?1. 解决存储空间不足的问题2. 解决权限问题3. 提

Spring Boot 集成 Quartz 使用Cron 表达式实现定时任务

《SpringBoot集成Quartz使用Cron表达式实现定时任务》本文介绍了如何在SpringBoot项目中集成Quartz并使用Cron表达式进行任务调度,通过添加Quartz依赖、创... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程