Bootloader板级启动开发工程 - 第1节

1. Bootloader概述

Bootloader(引导加载程序)是嵌入式系统上电后执行的第一段软件代码。它负责完成硬件初始化、建立内存映射、加载操作系统内核或应用程序镜像,并将控制权移交给目标程序。Bootloader 是硬件与操作系统之间的桥梁,其执行时间窗口极短,但对系统稳定性至关重要。

核心定义:Bootloader 是一段固化在非易失性存储器(如 Flash、ROM)中的启动代码,在系统复位后最先运行,完成从硬件初始化到操作系统启动的过渡。

Bootloader 的执行阶段

典型的 Bootloader 分为两个阶段执行,以适应不同硬件资源限制:

阶段 存储位置 主要任务 大小限制
Stage 1 ROM / 片上 Flash 基础 CPU 初始化、设置栈指针、拷贝 Stage 2 到 RAM 通常 < 4 KB
Stage 2 外部 Flash / 存储设备 完整硬件初始化(DRAM、时钟、外设)、文件系统支持、网络协议栈 几十 KB ~ 几百 KB

设计原则:Stage 1 必须足够精简,避免依赖复杂外设;Stage 2 可以引入更丰富的功能,如串口交互、网络下载、校验机制等。

1.2 Bootloader在嵌入式系统中的作用

在嵌入式系统中,Bootloader 承担着比通用计算机更关键的角色,主要体现在以下五个方面:

  1. 硬件初始化——设置 CPU 模式、关闭看门狗、初始化时钟和内存控制器,使系统达到可运行状态。
  2. 镜像加载与校验——从 Flash、SD 卡、网络或串口读取操作系统镜像,执行 CRC 或签名校验,确保镜像完整性。
  3. 启动参数传递——将硬件配置信息(如内存大小、设备树地址、启动模式)以参数形式传递给内核。
  4. 系统更新与恢复——提供固件升级接口(如 USB DFU、TFTP、XMODEM),在系统崩溃时进入恢复模式。
  5. 多启动支持——根据用户选择或硬件状态,从不同分区或存储介质启动不同版本的系统。

常见误区:Bootloader 不是操作系统的一部分,它独立于内核存在。错误的 Bootloader 配置可能导致系统无法启动,甚至损坏 Flash 分区表。

1.3 常见Bootloader类型

不同应用场景催生了多种 Bootloader 实现,下表对比了当前主流的四种 Bootloader:

名称 适用领域 主要特点 启动方式
U-Boot 嵌入式 Linux(ARM、RISC-V、MIPS、x86) 功能丰富、支持多种文件系统和网络协议、社区活跃 SPL → U-Boot proper → Kernel
GRUB x86 PC / 服务器(Linux、Windows) 支持多操作系统选择、模块化设计、配置文件驱动 BIOS/UEFI → GRUB Stage 1 → Stage 2 → OS
Coreboot x86 / ARM 高性能计算 极速启动(< 1 秒)、高度可定制、开源 Bootblock → Romstage → Ramstage → Payload
MCU Bootloader STM32、AVR、PIC 等单片机 轻量级、常驻 Flash、支持 IAP(在应用编程) 向量表重映射 → 跳转到应用程序

U-Boot 架构概览

U-Boot 是目前嵌入式 Linux 领域使用最广泛的 Bootloader,其内部结构清晰分为三层:

U-Boot 软件架构图 用户交互层(Shell / CLI / 环境变量) 命令与协议层 网络协议(TFTP / NFS / DHCP) | 文件系统(FAT / ext4 / SquashFS) 镜像解析(ELF / uImage / FIT) | 分区管理(MTD / GPT) 硬件抽象层(HAL / Driver) 串口 / GPIO / I2C / SPI / 以太网 / MMC / NAND Flash 定时器 / 中断控制器 / 时钟 / 电源管理 目标硬件平台(SoC / 开发板)

U-Boot 启动流程:SPL(Secondary Program Loader)→ U-Boot proper → 加载设备树(DTB)→ 启动内核。SPL 通常只有 16~32 KB,负责初始化 DRAM 并加载完整的 U-Boot。

GRUB 与 Coreboot 的定位差异

在 x86 生态中,GRUB 和 Coreboot 常被对比,但它们的职责层级不同:

  • GRUB 运行在 BIOS/UEFI 之上,是一个完整的 Bootloader,提供菜单、文件系统驱动和内核加载能力。
  • Coreboot 本身只做硬件初始化,不包含内核加载逻辑;它需要配合一个 Payload(如 SeaBIOS、GRUB、U-Boot)来完成引导。

下图展示了 Coreboot 的启动阶段划分:

Coreboot 启动阶段 Bootblock CPU 初始化 Romstage 内存初始化 Ramstage 外设枚举 Payload 加载 OS Coreboot 与 GRUB 的协作关系 Coreboot 完成硬件初始化后,将控制权交给 Payload Payload 可以是 GRUB、SeaBIOS 或 U-Boot,负责加载操作系统 这种分离设计使 Coreboot 可以保持极小的代码体积(~80 KB)

1.4 如何选择Bootloader

选择 Bootloader 时,需要根据项目需求评估以下关键因素:

评估维度 U-Boot GRUB Coreboot MCU Bootloader
硬件平台 ARM / RISC-V / MIPS / x86 x86 / x86_64 x86 / ARM STM32 / AVR / PIC
启动速度 中等(1~3 秒) 较慢(3~10 秒) 极快(< 1 秒) 极快(< 100 ms)
功能丰富度 极高 高 低(需 Payload) 低
社区支持 非常活跃 活跃 中等 厂商提供
典型场景 嵌入式 Linux 产品 PC / 服务器多系统 Chromebook / 高性能计算 物联网 / 工业控制

选型建议:对于资源受限的 MCU 项目,优先使用厂商提供的 Bootloader 或轻量级实现(如 STM32 系统自带 Bootloader);对于运行 Linux 的嵌入式系统,U-Boot 是事实标准;追求极致启动速度时,考虑 Coreboot + U-Boot 作为 Payload 的组合。