3. Linux BSP基础概念
在嵌入式 Linux 开发中,BSP(Board Support Package,板级支持包)是连接通用 Linux 内核与具体硬件板卡之间的“适配层”。对于 NXP i.MX9 这类应用处理器而言,芯片本身功能强大,但一块实际可运行的开发板还包含 DDR、eMMC、PMIC、以太网 PHY、Wi-Fi 模组、显示接口等外围器件。BSP 的职责,就是让 Linux 内核在这些具体硬件上正确启动、识别设备并稳定运行。
理解 BSP,不能只把它当成“一堆驱动代码”。更准确地说,BSP 是一套围绕目标板卡组织的软件集合,包括引导加载程序、内核配置与设备树、必要驱动、根文件系统构建配置以及烧录与调试工具。它既包含代码,也包含配置、脚本和构建规则。
3.1 BSP 的组成要素
一个完整的 i.MX9 Linux BSP 通常由以下要素构成:
- Bootloader:i.MX9 常用 U-Boot,负责初始化 DDR、时钟、串口等基础硬件,加载内核与设备树。
- Linux Kernel:包含与 i.MX9 相关的 SoC 支持、板级配置、设备树文件以及外设驱动。
- Device Tree:以 .dts/.dtsi 描述板级硬件连接,如 I2C 地址、GPIO 引脚、时钟源、电源域等。
- Root Filesystem:提供用户空间运行环境,如 BusyBox、systemd、库文件、应用程序和启动脚本。
- 工具链与构建系统:如 Yocto、Buildroot 或 NXP 提供的 SDK,用于交叉编译和镜像生成。
- 烧录与调试工具:如 UUU、mfgtool、OpenOCD、串口终端等。
这些要素不是孤立存在的,而是通过明确的启动链路和构建流程协同工作。下图展示了 i.MX9 BSP 的核心组成及其与内核、驱动、根文件系统之间的关系。
3.2 启动流程:从上电到用户空间
i.MX9 的典型启动流程可以分为以下几个阶段:
- Boot ROM:芯片上电后首先运行固化在片内的 Boot ROM,根据启动引脚或 eFuse 配置选择启动介质,如 eMMC、SD 卡或 QSPI Flash。
- SPL / U-Boot:Boot ROM 加载 SPL(Secondary Program Loader),SPL 初始化 DDR 后加载完整的 U-Boot。U-Boot 进一步初始化外设,并加载内核镜像与设备树。
- Kernel 启动:内核解压后开始运行,根据设备树识别硬件,加载对应驱动,挂载根文件系统。
- init 进程:内核启动第一个用户空间进程,通常是 BusyBox init 或 systemd,随后按配置启动各项服务。
下面是一段典型的 U-Boot 启动日志片段,可以看到内核与设备树的加载过程:
U-Boot 2023.04 (Jan 15 2024 - 10:23:45 +0800)
CPU: i.MX93 rev1.0 at 1700 MHz
Model: NXP i.MX93 EVK board
DRAM: 2 GiB
Core: 128 devices, 24 uclasses, devicetree: separate
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK
In: serial
Out: serial
Err: serial
Net: eth0: ethernet@428a0000
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc1 is current device
Reading from mmc 1:1...
Loading Image from mmc 1:1 at 0x80400000
Loading imx93-evk.dtb from mmc 1:1 at 0x83000000
## Booting kernel from Legacy Image at 80400000 ...
Image Name: Linux-6.1.36
Image Type: AArch64 Linux Kernel Image (uncompressed)
Data Size: 24567808 Bytes
Load Address: 0x80400000
Entry Point: 0x80400000
Verifying Checksum ... OK
Loading Device Tree to 0x83000000, end 0x8302a3f1 ... OK
Starting kernel ...
3.3 BSP 与内核、驱动、根文件系统的关系
很多初学者容易把 BSP 与内核混为一谈。实际上,BSP 是“面向板卡的适配集合”,而内核是“通用操作系统核心”。两者的关系可以这样理解:
| 对象 | 职责 | 与 BSP 的关系 |
|---|---|---|
| Linux 内核 | 进程调度、内存管理、文件系统、网络协议栈 | BSP 提供板级配置和设备树,内核提供通用框架 |
| 驱动 | 控制具体外设,如 I2C、SPI、GPIO、以太网 | BSP 包含或启用目标板所需驱动,并配置参数 |
| 设备树 | 描述硬件连接与资源分配 | BSP 的核心板级描述文件,内核据此加载驱动 |
| 根文件系统 | 提供用户空间程序、库和启动脚本 | BSP 构建系统负责生成并打包根文件系统镜像 |
| Bootloader | 初始化硬件并引导内核 | BSP 的重要组成部分,与板级 DDR 和启动介质强相关 |
核心结论:BSP 不是内核本身,而是让内核“认识”并“驱动”具体板卡的一整套适配层。没有 BSP,通用内核无法在 i.MX9 开发板上正常启动和运行。
3.4 常见误区与复盘
误区一:把设备树当成驱动。设备树只描述硬件信息,不包含驱动逻辑。驱动代码在内核中,设备树负责告诉内核“哪里有什么硬件”。
误区二:认为 BSP 只包含 U-Boot。U-Boot 只是 BSP 的一部分,内核配置、设备树、根文件系统构建规则同样属于 BSP 范畴。
误区三:忽略根文件系统与 BSP 的关联。根文件系统中的库版本、启动脚本、设备节点权限,都会影响 BSP 的整体可用性。
实践建议:在调试 i.MX9 BSP 时,建议按“Bootloader → 设备树 → 内核 → 根文件系统”的顺序逐级排查。先确认串口有输出,再确认 DDR 初始化正常,然后检查设备树是否匹配板卡,最后验证根文件系统能否挂载并进入用户空间。
掌握 BSP 的组成与启动流程,是后续进行 i.MX9 内核裁剪、驱动移植和系统定制的基础。只有理解 BSP 与内核、驱动、根文件系统之间的分工与协作,才能在遇到启动失败、设备识别异常等问题时快速定位到正确的层级。