在芯片启动过程中,Bootloader和BSP(板级支持包)是两个紧密相关但职责不同的核心概念。Bootloader 是启动流程的执行者,而 BSP 是支撑操作系统和 Bootloader 运行的软件基础设施。
Bootloader 的主要职责
Bootloader 是固化在芯片非易失性存储器中的一段小程序,是系统上电后运行的第一段软件代码。它的核心职责是完成硬件初始化和引导操作系统内核,其典型工作流程如下表所示:
| 阶段 | 主要职责 | 具体说明与代码示例 |
|---|---|---|
| 硬件初始化 | 建立最基本的运行环境 | 初始化 CPU、关闭看门狗、配置时钟、初始化内存控制器(如 SDRAM)、配置必要的 GPIO 和关闭中断等。这是后续所有操作的基础。 |
| 设备初始化 | 为加载内核镜像做准备 | 初始化用于传输内核镜像的存储设备(如 Flash、eMMC)和通信接口(如串口、网口),以便从特定位置读取数据。 |
| 加载内核镜像 | 将操作系统内核搬运到内存 | 从存储设备(或通过网络)将压缩或非压缩的内核镜像读取到指定的内存地址。 |
| 设置启动参数 | 向内核传递信息 | 准备并传递命令行参数 (bootargs)、内存分布、设备树 (dtb) 地址等关键信息给内核。 |
| 跳转执行 | 将控制权交给操作系统 | 最后,Bootloader 会跳转到内核在内存中的入口地址,将 CPU 的控制权彻底移交给操作系统,自身使命完成。 |
一个简化的 ARM Bootloader 早期汇编阶段代码示例如下:
@ 文件:start.S .global _start _start: @ 1. 设置CPU为SVC模式,并禁用中断 mrs r0, cpsr bic r0, r0, #0x1F orr r0, r0, #0x13 msr cpsr, r0 @ 2. 关闭看门狗定时器(假设WTCON地址为0xE2700000) ldr r0, =0xE2700000 mov r1, #0x0 str r1, [r0] @ 3. 初始化系统时钟(设置MPLL和UPLL,代码略) bl system_clock_init @ 4. 初始化内存控制器(SDRAM) bl mem_ctrl_init @ 5. 设置栈指针,为跳转到C语言代码做准备 ldr sp, =0x40000000 bl main @ 跳转到C语言的主函数在C语言的main函数中,会继续初始化串口、存储设备,并最终加载和启动内核。
Bootloader 与 BSP 的关系
BSP 是一个更广泛的软件包概念,它包含了使特定硬件板卡支持某个操作系统所需的所有底层软件。Bootloader 与 BSP 的关系可以从以下几个层面理解:
| 对比维度 | Bootloader | BSP (Board Support Package) |
|---|---|---|
| 定义与范畴 | 一段具体的引导程序,如 U-Boot、RedBoot。 | 一个软件包的集合,包含Bootloader、操作系统内核移植层、设备驱动等。 |
| 核心职责 | 引导启动:负责从硬件上电到操作系统内核运行之间的过渡。 | 硬件抽象与支持:为操作系统(及Bootloader)提供访问和管理底层硬件的统一接口。 |
| 内容组成 | 通常是一个独立的可执行映像。 | 包含Bootloader源码/配置、内核移植补丁、设备驱动、硬件配置文件(如设备树)、根文件系统等。 |
| 依赖关系 | 依赖BSP中的硬件抽象:Bootloader的驱动代码(如串口、Flash驱动)往往复用或参考BSP中提供的底层硬件操作函数。 | 包含或为Bootloader提供支持:BSP的开发会确保Bootloader能在目标板上正常运行,为其提供必要的硬件支持。 |
| 在启动流程中的位置 | 运行在操作系统内核之前,是启动链条的第一环。 | 贯穿始终:其部分代码(硬件初始化)在Bootloader阶段被使用;其主体(设备驱动)在内核启动后被加载。 |
两者关系的核心概括为:BSP 是“土壤”和“基础设施”,而 Bootloader 是生长在这片土壤上、负责执行“破土而出”任务的“种子”或“先锋”。
具体来说:
- 开发层面:在为一个新硬件平台开发 BSP 时,开发人员需要同时适配 Bootloader 和操作系统内核。例如,在 Linux BSP 开发中,需要修改 U-Boot 以适应新的板级硬件,同时也要修改 Linux 内核的设备树和驱动来匹配同一块板卡。因此,Bootloader 的移植是 BSP 开发的关键组成部分。
- 功能层面:Bootloader 执行的许多低级硬件初始化操作(如时钟、内存初始化),其知识和代码基础来源于对该硬件平台的 BSP 开发经验。在像 VxWorks 这样的操作系统中,其 Bootloader(如 bootrom)与 BSP 的关联更为紧密,甚至可能直接从 BSP 的配置和代码中编译生成。
- 最终目标:两者的最终目标是一致的,即让操作系统能够在一个特定的硬件平台上正确运行。Bootloader 负责“唤醒”硬件并“递交”给操作系统,而 BSP 则确保操作系统在接手后能“驱动”和“管理”好所有硬件资源。
以一个典型的嵌入式 Linux 系统开发为例:
- BSP 提供商(如芯片原厂)会发布一个完整的软件包,其中包含了:
- 适配好的U-Boot(Bootloader)
- 打好了板级补丁的Linux 内核
- 各类设备驱动(如网卡、LCD、USB)
- 该平台的设备树源文件(
.dts)
- 开发者使用这个 BSP 包,首先编译和烧写 U-Boot。U-Boot 启动后,会根据 BSP 中定义的设备树信息来正确识别硬件,然后加载 BSP 中提供的内核镜像,从而完成整个系统的启动。
综上所述,Bootloader 是启动过程中一个具体、狭义的执行实体,而 BSP 是一个为支持整个操作系统(包括其启动过程)而存在的广义软件集合。Bootloader 是 BSP 在系统启动阶段的具体体现和关键抓手。
参考来源
- 关于驱动程序与BSP的区别
- BSP Bootloader基本概念
- 什么是BSP?理解LINUX BSP
- VxWorks引导启动过程
- BSP,讲的很好。
- BSP Bootloader