uboot执行流程分析2


以下是基于 U-Boot 源码的详细执行流程分析(以 ARMv7 架构为例,结合 U-Boot 2023.04 版本源码)。由于篇幅限制,我会聚焦关键代码段并解释其逻辑,但会覆盖所有核心阶段。


1. 启动入口(_start)

文件: arch/arm/lib/vectors.S
功能: 定义 CPU 的异常向量表和初始跳转。

/* arch/arm/lib/vectors.S */
.globl _start
_start:
    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
  • 关键点:
    • 所有 ARM 异常向量(Reset、Undef、IRQ 等)在此定义。
    • 复位后执行第一条指令 b reset,跳转到 reset 标签。

2. 低级初始化(reset)

文件: arch/arm/cpu/armv7/start.S
功能: 关闭 MMU/Cache、初始化关键硬件、设置栈、跳转到 C 环境。

2.1 关闭 MMU 和 Cache
reset:
    /* 关闭 MMU 和 Cache */
    mrc p15, 0, r0, c1, c0, 0   @ 读取 CP15 控制寄存器 (SCTLR)
    bic r0, r0, #0x00002000     @ 关闭指令 Cache (bit 12)
    bic r0, r0, #0x00000005     @ 关闭数据和 MMU (bits 0, 2)
    mcr p15, 0, r0, c1, c0, 0   @ 写回 SCTLR
2.2 设置 CPU 模式和栈
    /* 进入 SVC 模式并设置栈 */
    msr cpsr_c, #0x13           @ SVC 模式, 关闭中断 (IRQ 和 FIQ)
    ldr sp, =CONFIG_SYS_INIT_SP_ADDR  @ 初始化栈地址(通常在链接脚本定义)
2.3 调用板级初始化 lowlevel_init
    /* 执行板级特定初始化 */
    bl  lowlevel_init           @ 跳转到板级 lowlevel_init(时钟、DDR 等)

文件: arch/arm/cpu/armv7/lowlevel_init.S 或板级自定义文件
示例(简化版):

ENTRY(lowlevel_init)
    /* 初始化时钟 */
    ldr r0, =0x12345678         @ 时钟控制寄存器地址
    ldr r1, =0xABCD             @ 配置值
    str r1, [r0]

    /* 初始化 DDR 控制器 */
    ldr r0, =0xDEADBEEF         @ DDR 控制器基地址
    ldr r1, =0x5A5A             @ 配置参数
    str r1, [r0, #0x10]         @ 写入时序寄存器
    bx  lr                      @ 返回
ENDPROC(lowlevel_init)
2.4 重定位 U-Boot 到 RAM

功能:是重定位的 物理基础(代码复制到 RAM),确保后续代码能运行

    /* 检查是否需要重定位 */
    ldr r0, =_start             @ 当前代码地址(通常为 ROM/Flash 地址)
    ldr r1, =CONFIG_SYS_TEXT_BASE @ 目标地址(RAM 地址)
    cmp r0, r1
    beq skip_relocate           @ 如果已在 RAM 中,跳过重定位

    /* 复制代码到 RAM */
    ldr r2, =_end               @ 代码结束地址
    sub r2, r2, r0              @ 计算代码长度
    mov r4, r1                  @ 目标地址
    bl  copy_code               @ 调用复制函数

copy_code:
    ldr r3, [r0], #4            @ 从源地址读取 4 字节
    str r3, [r4], #4            @ 写入目标地址
    subs r2, r2, #4             @ 长度减 4
    bgt copy_code               @ 循环直到复制完成

skip_relocate:
    /* 重定位完成后跳转到 RAM 中的地址 */
    ldr pc, =after_relocation   @ 强制跳转到 RAM 中的代码

3. C 语言环境初始化(board_init_f)

文件: common/board_f.c
功能: 初始化全局数据结构 gd,执行一系列硬件初始化。

3.1 全局数据结构 gd 初始化
/* 定义全局数据指针 */
DECLARE_GLOBAL_DATA_PTR;  // 实际为 register volatile gd_t *gd asm ("r9")

void board_init_f(ulong boot_flags)
{
   
   
    /* 初始化 gd 结构体 */
    gd = (gd_t *)CONFIG_SYS_INIT_SP_ADDR;  // 通常栈顶预留空间给 gd
    memset(gd, 0, sizeof(gd_t));

    /* 填充 gd 的初始值 */
    gd->flags = boot_flags;
    gd->baudrate = CONFIG_BAUDRATE;

    /* 执行初始化序列 */
    initcall_run_list(init_sequence_f);
}
3.2 初始化序列 init_sequence_f

定义(部分):

static const init_fnc_t init_sequence_f[] = {
   
   
    setup_mon_len,           /* 计算 U-Boot 代码长度 */
    initf_malloc,            /* 初始化早期内存分配器 */
    arch_cpu_init,           /* 架构相关初始化(如缓存) */
    mach_cpu_init,           /* 芯片特定初始化 */
    initf_dm,                /* 初始化设备模型 */
    board_e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值