2. Bootloader 概念与作用

2.1 Bootloader 定义

Bootloader(引导加载程序)是系统上电后、操作系统内核运行之前执行的第一段软件代码。它负责完成从硬件复位到操作系统启动之间的所有过渡工作,是嵌入式系统中硬件与软件之间的桥梁。

在 ARM 嵌入式系统中,Bootloader 通常存储在非易失性存储器(如 NOR Flash、NAND Flash、eMMC 或 SD 卡)的固定起始位置。处理器复位后,硬件会自动从该位置加载并执行 Bootloader 的第一条指令。

关键理解: Bootloader 不是操作系统的一部分,而是一个独立的、与硬件紧密耦合的底层软件。它的存在使得操作系统可以以硬件无关的方式加载和运行。

2.2 Bootloader 在系统启动中的位置

从系统上电到操作系统完全启动,整个流程可以分为四个阶段。Bootloader 位于第二阶段,承担承上启下的关键角色。

系统启动流程中的 Bootloader 位置 阶段 1 上电复位 ROM Boot / BootROM 阶段 2 Bootloader 硬件初始化 → 加载 OS 阶段 3 操作系统内核 内核解压与初始化 阶段 4 用户空间 说明: • BootROM(阶段1)固化在芯片内部,不可修改,负责从存储介质加载 Bootloader。 • Bootloader(阶段2)是开发者可控的第一段代码,负责初始化硬件并加载操作系统。 • 阶段3和阶段4由操作系统接管,Bootloader 在跳转后不再参与系统运行。

2.3 Bootloader 的主要功能

Bootloader 的核心职责可以归纳为两大阶段:硬件初始化和操作系统加载。下表列出了每个阶段的具体任务。

功能阶段 具体任务 说明
硬件初始化 CPU 模式与异常向量设置 设置处理器为 SVC 模式,配置异常向量表基地址
时钟系统配置 配置 PLL、分频器,使 CPU 和总线工作在目标频率
内存控制器初始化 配置 SDRAM/DDR 控制器时序,使能内存空间
外设基本初始化 初始化串口、定时器、中断控制器等基础外设
操作系统加载 从存储介质读取内核映像 从 Flash、SD 卡、网络等介质读取内核和设备树
验证与解压 校验映像完整性,解压压缩格式的内核(如 zImage)
跳转到内核入口 设置启动参数(ATAG 或设备树),跳转到内核起始地址
硬件初始化深度提示: 在 ARM 平台上,Bootloader 的硬件初始化通常分为两个子阶段:汇编阶段(Stage 1)和 C 语言阶段(Stage 2)。汇编阶段负责设置栈指针、清零 BSS 段、拷贝代码到 RAM;C 语言阶段则完成时钟、内存、串口等复杂外设的初始化。

2.4 常见 Bootloader 对比

嵌入式 ARM 领域存在多种 Bootloader 方案,各自适用于不同的场景。下表从多个维度对比了三种主流 Bootloader。

特性 U-Boot Barebox AT91Bootstrap
开发者 DENX 社区 / 全球贡献者 Pengutronix / Sascha Hauer Microchip (Atmel)
主要应用平台 ARM、x86、RISC-V、MIPS 等 ARM、x86 Atmel/Microchip ARM SoC
代码规模 大(约 50 万行) 中等(约 15 万行) 小(约 2 万行)
启动速度 中等(可优化) 较快 极快
设备树支持 完整支持(FDT) 完整支持(FDT) 有限支持
交互式 Shell 有(功能丰富) 有(类 POSIX) 无(仅串口打印)
网络引导 TFTP、NFS 支持完善 TFTP、NFS 支持 不支持
适用场景 通用嵌入式系统、开发板 工业控制、快速启动需求 Atmel 专用芯片、资源受限系统

2.5 三种 Bootloader 的架构对比

下图展示了 U-Boot、Barebox 和 AT91Bootstrap 在软件架构上的核心差异。

三种常见 Bootloader 架构对比 U-Boot Shell / 命令行接口 命令解析器 设备驱动框架 文件系统支持 硬件抽象层 (HAL) Barebox POSIX 风格 Shell 设备模型 (Driver Model) 参数管理框架 分区与文件系统 硬件抽象层 (HAL) AT91Bootstrap 主控逻辑 (Main) 硬件初始化序列 存储介质驱动 映像加载器 硬件寄存器操作

2.6 选择 Bootloader 的考量因素

在实际工程中,选择哪种 Bootloader 需要综合评估以下因素:

  • 硬件平台兼容性: 确认 Bootloader 是否支持目标 SoC 和板级外设。
  • 启动时间要求: 对于汽车电子、工业控制等实时性要求高的场景,优先选择启动快的方案(如 Barebox 或 AT91Bootstrap)。
  • 功能需求: 是否需要网络引导、文件系统支持、交互式调试等高级功能。
  • 社区与维护: U-Boot 社区活跃度最高,文档和补丁支持最完善;AT91Bootstrap 由原厂维护,适合 Atmel 专用项目。
  • 代码复杂度与可移植性: 小型项目或资源受限系统更适合轻量级 Bootloader。
工程实践警告: 不要盲目选择功能最丰富的 Bootloader。在资源受限的 ARM Cortex-M 或低端 Cortex-A 平台上,U-Boot 的代码体积和启动延迟可能成为瓶颈。建议先评估硬件资源(RAM 大小、Flash 容量、启动时间预算),再做出选择。

2.7 Bootloader 与设备树的关系

在现代 ARM Linux 系统中,Bootloader 与设备树(Device Tree)紧密协作。Bootloader 负责将设备树二进制文件(.dtb)从存储介质加载到内存,并将设备树地址传递给内核。设备树描述了硬件拓扑结构,使得内核可以以硬件无关的方式访问外设。

/* U-Boot 中加载设备树的典型命令序列 */
# 从 SD 卡加载内核和设备树到内存
fatload mmc 0:1 0x42000000 zImage
fatload mmc 0:1 0x43000000 imx6ull-evk.dtb

# 设置启动参数,传递设备树地址
setenv bootargs console=ttymxc0,115200 root=/dev/mmcblk0p2 rw

# 启动内核,同时传递设备树地址
bootz 0x42000000 - 0x43000000

上述命令展示了 Bootloader 在加载操作系统过程中的具体操作:先读取内核映像和设备树到指定内存地址,然后通过 bootz 命令将控制权交给内核,同时将设备树地址作为参数传递。