UBOOT启动流程详解-现代FIT设备加载
UBOOT启动流程详解
1. UBOOT启动概述
UBOOT(Universal Bootloader)是一个开源的引导加载程序,支持多种架构和启动方式。它的主要作用是初始化硬件、加载操作系统内核,并将控制权转交给内核。
2. 传统启动流程
2.1 基本启动阶段
ROM Code → SPL/TPL → UBOOT → Kernel
- ROM Code阶段:芯片固化代码,负责最基础的硬件初始化
- SPL/TPL阶段:二级引导加载程序
- UBOOT主程序:完整的引导环境
- 内核启动:移交控制权给操作系统
2.2 传统启动方式特点
- 使用简单的二进制镜像格式
- 内核和设备树分离加载
- 启动参数通过命令行传递
3. SPL(Secondary Program Loader)启动
3.1 SPL的作用
SPL是UBOOT的精简版本,主要功能:
- 初始化DDR内存
- 设置时钟系统
- 加载主UBOOT程序
- 提供早期调试接口
3.2 SPL启动流程
ROM → SPL初始化 → DDR配置 → 加载UBOOT → 跳转到UBOOT
3.3 SPL配置要点
// SPL配置示例
#define CONFIG_SPL_FRAMEWORK
#define CONFIG_SPL_TEXT_BASE 0x00000000
#define CONFIG_SPL_MAX_SIZE 0x8000
#define CONFIG_SPL_STACK 0x00080000
4. TPL(Tertiary Program Loader)启动
4.1 TPL使用场景
TPL用于更复杂的启动需求:
- 极度受限的存储空间
- 需要多级引导的场景
- 安全启动要求
4.2 三级启动流程
ROM → TPL → SPL → UBOOT → Kernel
5. FDT(Flattened Device Tree)启动
5.1 FDT介绍
设备树是描述硬件信息的数据结构,以扁平化格式存储。
5.2 FDT启动流程
# 加载设备树
load mmc 0:1 0x43000000 /boot/dtb/xxx.dtb# 设置设备树地址
fdt addr 0x43000000# 修改设备树(可选)
fdt set /chosen bootargs "console=ttyS0,115200"# 启动内核
bootz 0x41000000 - 0x43000000
5.3 FDT相关命令
# 显示设备树信息
fdt print# 修改设备树节点
fdt set /path/to/node property value# 删除设备树节点
fdt rm /path/to/node
6. FIT(Flattened Image Tree)启动
这个是从瑞芯微官方上找的图,很好的解释了启动流程。左侧的那个流程图是使用他们提供的idbloader的方法,是不开源的。右侧是开源的方法。
6.1 FIT格式优势
- 将内核、设备树、initramfs打包在一起
- 支持数字签名验证
- 支持多配置选择
- 提供完整性校验
- 支持FDT Overlay功能
- 支持多种加载策略
6.2 FIT的多种使用方式
6.2.1 基础单一配置FIT
FIT Image
├── kernel@1 (内核镜像)
├── fdt@1 (设备树)
├── ramdisk@1 (初始化文件系统)
└── configurations└── config@1 (配置信息)
6.2.2 多内核多设备树配置
FIT Image
├── kernel@1 (ARM64内核)
├── kernel@2 (ARM32内核)
├── fdt@1 (主板设备树)
├── fdt@2 (扩展板设备树)
├── ramdisk@1 (通用initramfs)
└── configurations├── config@1 (ARM64 + 主板)├── config@2 (ARM64 + 扩展板)└── config@3 (ARM32 + 主板)
6.2.3 FDT Overlay配置
FIT Image
├── kernel@1 (内核镜像)
├── fdt@1 (基础设备树)
├── fdt@2 (Overlay 1 - LCD支持)
├── fdt@3 (Overlay 2 - 摄像头支持)
├── fdt@4 (Overlay 3 - WiFi模块)
└── configurations├── config@1 (基础配置)├── config@2 (带LCD)├── config@3 (带LCD+摄像头)└── config@4 (全功能配置)
6.3 FDT Overlay详解
6.3.1 什么是FDT Overlay
FDT Overlay允许在运行时动态修改设备树,无需重新编译整个设备树。这对于:
- 模块化硬件设计
- 可选外设支持
- 不同硬件版本兼容
- 动态功能启用/禁用
6.3.2 不使用Overlay的传统配置
/dts-v1/;
/ {description = "Traditional FIT without overlays";#address-cells = <1>;images {kernel {data = /incbin/("./zImage");type = "kernel";arch = "arm";os = "linux";compression = "none";load = <0x80008000>;entry = <0x80008000>;};fdt-1 {description = "Device tree for board foo-reva";data = /incbin/("./foo-reva.dtb");type = "flat_dt";arch = "arm";compression = "none";};fdt-2 {description = "Device tree for board foo-revb";data = /incbin/("./foo-revb.dtb");type = "flat_dt";arch = "arm";compression = "none";};};configurations {default = "config-1";config-1 {description = "Boot kernel with foo-reva board";kernel = "kernel";fdt = "fdt-1";};config-2 {description = "Boot kernel with foo-revb board";kernel = "kernel";fdt = "fdt-2";};};
};
6.3.3 使用Overlay的现代配置
/dts-v1/;
/ {description = "FIT with FDT overlays";#address-cells = <1>;images {kernel {data = /incbin/("./zImage");type = "kernel";arch = "arm";os = "linux";compression = "none";load = <0x80008000>;entry = <0x80008000>;};base_fdt {description = "Base device tree";data = /incbin/("./base.dtb");type = "flat_dt";arch = "arm";compression = "none";};fdt_overlay_lcd {description = "LCD overlay";data = /incbin/("./lcd-overlay.dtbo");type = "flat_dt";arch = "arm";compression = "none";};fdt_overlay_camera {description = "Camera overlay";data = /incbin/("./camera-overlay.dtbo");type = "flat_dt";arch = "arm";compression = "none";};fdt_overlay_wifi {description = "WiFi overlay";data = /incbin/("./wifi-overlay.dtbo");type = "flat_dt";arch = "arm";compression = "none";};};configurations {default = "config_base";config_base {description = "Basic configuration";kernel = "kernel";fdt = "base_fdt";};config_lcd {description = "Configuration with LCD";kernel = "kernel";fdt = "base_fdt";fdt-overlay-0 = "fdt_overlay_lcd";};config_full {description = "Full featured configuration";kernel = "kernel";fdt = "base_fdt";fdt-overlay-0 = "fdt_overlay_lcd";fdt-overlay-1 = "fdt_overlay_camera";fdt-overlay-2 = "fdt_overlay_wifi";};};
};
6.3.4 Overlay与特性选择配置
/dts-v1/;
/ {description = "FIT with overlays and feature selection";#address-cells = <1>;images {kernel {data = /incbin/("./zImage");type = "kernel";arch = "arm";os = "linux";compression = "none";load = <0x80008000>;entry = <0x80008000>;};base_fdt {data = /incbin/("./base.dtb");type = "flat_dt";arch = "arm";compression = "none";};/* 功能性Overlay */overlay_spi {data = /incbin/("./spi-overlay.dtbo");type = "flat_dt";arch = "arm";compression = "none";};overlay_i2c {data = /incbin/("./i2c-overlay.dtbo");type = "flat_dt";arch = "arm";compression = "none";};overlay_uart {data = /incbin/("./uart-overlay.dtbo");type = "flat_dt";arch = "arm";compression = "none";};};configurations {default = "config_minimal";config_minimal {description = "Minimal configuration";kernel = "kernel";fdt = "base_fdt";};config_comm {description = "Communication interfaces";kernel = "kernel";fdt = "base_fdt";fdt-overlay-0 = "overlay_spi";fdt-overlay-1 = "overlay_i2c";fdt-overlay-2 = "overlay_uart";};};
};
6.4 FIT启动命令详解
6.4.1 基础FIT启动
# 加载FIT镜像
load mmc 0:1 0x43000000 /boot/image.fit# 查看FIT镜像信息
iminfo 0x43000000# 使用默认配置启动
bootm 0x43000000# 指定配置启动
bootm 0x43000000#config_lcd
6.4.2 动态选择配置
# 根据硬件检测选择配置
if gpio input 100; thensetenv fit_config "config_full"
elsesetenv fit_config "config_base"
fi# 使用选定的配置启动
bootm 0x43000000#${fit_config}
6.4.3 环境变量控制
# 设置默认FIT配置
setenv fit_config "config_lcd"# 设置FIT镜像路径
setenv fit_image "/boot/system.fit"# 自动化启动脚本
setenv bootcmd_fit "load mmc 0:1 0x43000000 ${fit_image}; bootm 0x43000000#${fit_config}"
6.5 Overlay设备树编写
6.5.1 LCD Overlay示例
// lcd-overlay.dts
/dts-v1/;
/plugin/;/ {compatible = "vendor,board";fragment@0 {target-path = "/";__overlay__ {backlight: backlight {compatible = "gpio-backlight";gpios = <&gpio 18 0>;default-on;};};};fragment@1 {target = <&i2c1>;__overlay__ {touchscreen@38 {compatible = "edt,edt-ft5306";reg = <0x38>;interrupt-parent = <&gpio>;interrupts = <25 2>;};};};
};
6.5.2 编译Overlay
# 编译设备树Overlay
dtc -@ -I dts -O dtb -o lcd-overlay.dtbo lcd-overlay.dts# 创建包含Overlay的FIT镜像
mkimage -f image.its image.fit
6.6 高级FIT特性
6.6.1 压缩支持
kernel {data = /incbin/("./zImage.gz");type = "kernel";arch = "arm";os = "linux";compression = "gzip"; // 支持gzip压缩load = <0x80008000>;entry = <0x80008000>;
};
6.6.2 签名验证
kernel {data = /incbin/("./zImage");type = "kernel";arch = "arm";os = "linux";compression = "none";load = <0x80008000>;entry = <0x80008000>;signature {algo = "sha256,rsa2048";key-name-hint = "dev";};
};
6.6.3 多架构支持
configurations {config_arm64 {description = "ARM64 configuration";kernel = "kernel_arm64";fdt = "base_fdt_arm64";};config_arm32 {description = "ARM32 configuration";kernel = "kernel_arm32";fdt = "base_fdt_arm32";};
};
7. UBOOT启动参数详解
7.1 环境变量设置
# 设置启动参数
setenv bootargs "console=ttyS0,115200 root=/dev/mmcblk0p2 rw"# 设置启动命令
setenv bootcmd "load mmc 0:1 0x41000000 /boot/zImage; load mmc 0:1 0x43000000 /boot/board.dtb; bootz 0x41000000 - 0x43000000"# 保存环境变量
saveenv
7.2 常用启动参数
# 控制台设置
console=ttyS0,115200# 根文件系统
root=/dev/mmcblk0p2
rootfstype=ext4
rw# 内存设置
mem=1024M# 调试参数
debug
loglevel=7# 网络启动
ip=dhcp
nfsroot=192.168.1.100:/nfs/rootfs
7.3 启动模式选择
# SD卡启动
setenv bootcmd "run mmcboot"# 网络启动
setenv bootcmd "run netboot"# NAND启动
setenv bootcmd "run nandboot"# USB启动
setenv bootcmd "run usbboot"
8. 高级启动特性
8.1 安全启动
# 验证签名
verified_boot=1# 设置公钥
setenv bootargs "${bootargs} dm-verity.public_key=/etc/keys/pubkey.pem"
8.2 A/B系统切换
# 设置当前启动分区
setenv boot_slot a# 启动脚本
if test "${boot_slot}" = "a"; thensetenv bootargs "${bootargs} root=/dev/mmcblk0p2"
elsesetenv bootargs "${bootargs} root=/dev/mmcblk0p3"
fi
8.3 故障恢复
# 设置启动计数
setenv bootcount 0# 启动失败处理
if test "${bootcount}" -gt "3"; thenecho "Boot failed, entering recovery mode"run recoveryboot
fi
9. 调试和故障排除
9.1 调试命令
# 显示环境变量
printenv# 内存操作
md 0x41000000 0x100 # 显示内存内容
mw 0x41000000 0x12345678 1 # 写入内存# 存储设备操作
mmc info # 显示MMC信息
mmc part # 显示分区信息
10. 总结
UBOOT提供了多种灵活的启动方式:
- 传统方式:简单直接,适合开发调试
- SPL/TPL:适合存储受限和复杂初始化场景
- FDT启动:现代Linux系统的标准方式
- FIT启动:安全启动和产品化部署的首选