总体流程概览(ARM 平台,Device Tree 支持)
[上电 / 复位]
↓
[Boot ROM (SoC 内部)]
↓
[1st Stage Bootloader (如 SPL)]
↓
[2nd Stage Bootloader: U-Boot]
↓
[Load Linux Kernel、DTB、Initramfs]
↓
[设置内核启动参数/设备树/内存布局]
↓
[跳转到内核入口 __start(),Kernel 开始执行]
一、上电后的 BootROM 阶段(由 SoC 厂商固化)
- 通常由 ARM SoC 厂商提供,不可修改;
- 功能:初始化 Boot 设备(SPI-NAND、eMMC、SD、USB等);
- 加载 SPL(二级引导前的小型启动代码)到 SRAM,跳转执行。
二、SPL(Secondary Program Loader)阶段
功能:
- 初始化 DRAM;
- 加载完整的 U-Boot 镜像到内存;
- 跳转到 U-Boot。
注意:若 SoC 有 SRAM 限制严重,必须使用 SPL 机制;否则直接进入 U-Boot。
三、U-Boot 主程序阶段(bootloader)
这是 加载并启动 Linux 的关键阶段。
1. 加载内核镜像、设备树、initramfs(可选)
- 一般从 eMMC/NAND/SD 卡/FAT/ext4 文件系统中读取:
ext4load mmc 0:1 0x80000 Image # 加载内核
ext4load mmc 0:1 0x40000 dtb # 加载设备树
ext4load mmc 0:1 0x2000000 initrd.img # 可选加载 initramfs
U-Boot 通常使用如下内存地址布局(不同平台略有不同):
模块 | 地址(示例) |
---|---|
kernel | 0x80000 或 0x80080000 |
dtb | 0x40000 或 0x83000000 |
initrd | 0x2000000 |
2. 设置 bootargs / ATAG / FDT 参数
- 设置传给内核的启动参数(cmdline):
setenv bootargs "console=ttyAMA0 root=/dev/mmcblk0p2 rootwait"
- ARMv7: 使用
ATAG
参数结构体(较老) - ARMv8: 使用设备树(FDT)
U-Boot 通过环境变量 bootargs
构造 cmdline
。
3. 调用 bootm / booti 命令启动内核
bootm
:用于启动传统的uImage
(带 U-Boot header)booti
:用于启动裸内核Image
(AArch64)bootz
:启动zImage
(压缩内核)
示例命令:
booti 0x80000 - 0x40000
# │ │ └── 设备树地址
# │ └── initrd(若无填 -)
# └── kernel image 加载地址
四、U-Boot 跳转到 Linux 内核入口
在调用 booti/bootm
时,U-Boot 做了以下事情:
设置 CPU 运行状态
- ARMv7:设置为 SVC 模式(关闭中断);
- ARMv8:设置
EL2 → EL1
,以 EL1 执行内核; - 关闭 MMU、Cache,或根据配置保留 L2;
设置寄存器
ARMv7:
- R0 = 0(机器 ID)
- R1 = 机器 ID(老方式)
- R2 = ATAG 地址或 DTB 地址
ARMv8:
- x0 = FDT blob 地址(必须)
- x1~x3 = 0
最后使用汇编跳转:
# ARMv7:
mov r0, #0
ldr r1, =machine_id
ldr r2, =atags_addr ; 或 dtb
mov pc, r0 ; 跳转到内核入口
# ARMv8:
mov x0, dtb_addr
br x1 ; x1 指向 kernel __start
五、Linux 内核执行入口 (__start)
内核镜像的起始点通常是:
// ARMv8-A arch/arm64/kernel/head.S
ENTRY(__start)
// 关闭 MMU/Cache(如果 U-Boot 没做)
// 设置页表、栈、EL级别
// 跳转到 start_kernel()
总结:U-Boot 启动 Linux 的关键点
阶段 | 关键任务 |
---|---|
SPL | 初始化 RAM,加载 U-Boot |
U-Boot | 初始化设备、加载 kernel/dtb/initrd |
设置参数 | 设定 bootargs,填充 FDT |
跳转 | 设置寄存器、进入内核入口 |
内核启动 | 进入 start_kernel(),开始内核世界 |
推荐配置文件(U-Boot)
在移植或开发过程中,关注:
include/configs/xxx.h
:配置内存映射、启动参数;board/xxx/xxx.c
:板级初始化;cmd/booti.c
/cmd/bootm.c
:启动命令实现;arch/arm/lib/bootm.c
:真正的跳转代码。