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 的核心组成及其与内核、驱动、根文件系统之间的关系。

i.MX9 Linux BSP 组成与启动关系 Bootloader U-Boot / SPL Linux Kernel SoC 支持 + 驱动 Device Tree .dts / .dtsi Root Filesystem BusyBox / systemd 构建与烧录工具 Yocto / UUU i.MX9 硬件板卡 DDR / eMMC / PMIC 匹配硬件 挂载 加载 描述 运行于 生成 BSP 与内核、驱动、根文件系统的关系 内核提供框架 进程调度 / 内存 / VFS 驱动适配硬件 I2C / SPI / GPIO / 网络 根文件系统提供用户空间 库 / 应用 / 启动脚本

3.2 启动流程:从上电到用户空间

i.MX9 的典型启动流程可以分为以下几个阶段:

  1. Boot ROM:芯片上电后首先运行固化在片内的 Boot ROM,根据启动引脚或 eFuse 配置选择启动介质,如 eMMC、SD 卡或 QSPI Flash。
  2. SPL / U-Boot:Boot ROM 加载 SPL(Secondary Program Loader),SPL 初始化 DDR 后加载完整的 U-Boot。U-Boot 进一步初始化外设,并加载内核镜像与设备树。
  3. Kernel 启动:内核解压后开始运行,根据设备树识别硬件,加载对应驱动,挂载根文件系统。
  4. 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 与内核、驱动、根文件系统之间的分工与协作,才能在遇到启动失败、设备识别异常等问题时快速定位到正确的层级。