UBoot结构分析
2025-11-07
5
0
boot.lds/u-boot.map
UBoot的入口函数位于arch/arm/cpu/u-boot.lds中,不过这只是一个模板代码,真正的代码是uboot编译后生成的u-boot.lds,位于源文件根目录中。
u-boot.lds是uboot编译后的链接器脚本。主要定义了生成的uboot文件的大小端、入口函数,起始地址,代码段、数据段等。
- 起始地址:0x00000000
- 架构:ARM32小端,所有段4字节对齐
- 入口:、_start
u-boot.map描述了内存分布
| 变量 | 数值 | 描述 |
|---|---|---|
| __image_copy_start | 0x87800000 | uboot 拷贝的首地址,代码段的起始地址,中断向量的起妈地址 |
| __image_copy_end | 0x8785dd54 | uboot 拷贝的结束地址 |
| __rel_dyn_start | 0x8785dd54 .rel.dyn | 段起始地址 |
| __rel_dyn_end | 0x878668f4 .rel.dyn | 段结束地址 |
| _image_binary_end | 0x878668f4 | 镜像结束地址 |
| __bss_start | 0x8785dd54 | .bss 段起始地址 |
| __bss_end | 0x878a8e74 | .bss 段结束地址 |
u-boot.lds中定义了入口函数为_start,该函数位于arch/arm/lib/vectors.S
_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
可以看到,_start前跳到reset,而reset之后就是中断向量。
reset位\arch\arm\cpu\armv7\start.S中
.globl reset
.globl save_boot_params_ret
reset:
/* Allow the board to save important registers */
b save_boot_params
save_boot_params_ret:
/*
* disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
* except if in HYP mode already
*/
mrs r0, cpsr
and r1, r0, #0x1f @ mask mode bits 获取低5位,即CPU工作模式
teq r1, #0x1a @ test for HYP mode 是不是HYP
bicne r0, r0, #0x1f @ clear all mode bits,
orrne r0, r0, #0x13 @ set SVC mode,设置为SVC模式
orr r0, r0, #0xc0 @ disable FIQ and IRQ,关闭中断
msr cpsr,r0 //回写r0->cpsr
reset直接跳到save_boot_params
ENTRY(save_boot_params)
b save_boot_params_ret @ back to my caller
ENDPROC(save_boot_params)
.weak save_boot_params
save_boot_params中直接跳到save_boot_params_ret,而save_boot_params_ret函数是获取cssp寄存器的低5位,即可获取当前CPU的状态。详见https://www.pciee.com/article/detail-210.html
继续执行:
/*
* Setup vector:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
* Continue to use ROM code vector only in OMAP4 spl)
*/
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
bic r0, #CR_V @ V = 0
mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register
/* Set vector address in CP15 VBAR register */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#endif
/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15 //调用cpu_init_cp15,cpu15相关的,如关闭MMU
bl cpu_init_crit //调用cpu_init_crit,调用 lowlevel_init,堆栈指针设置等,CPU类型判断待
#endif
bl _main //调用——main函数

_main
_main 函数定义在文件 arch/arm/lib/crt0.S
UBOOT环境配置及系统烧写





