1. 课程导入与BSP全景

在嵌入式Linux开发中,BSP(Board Support Package,板级支持包)是连接芯片原厂、板卡硬件与上层应用的桥梁。对于NXP i.MX系列处理器而言,BSP不仅包含U-Boot、Linux内核、设备树和根文件系统,还包含Yocto构建系统、工具链、固件以及一系列板级配置文件。理解BSP的组成与源码树结构,是后续进行硬件适配、驱动开发和系统裁剪的前提。

一、i.MX Linux BSP的组成

NXP官方发布的i.MX Linux BSP通常以Yocto Project的BSP Layer形式提供,核心组件包括:

  • U-Boot:负责上电初始化、DDR训练、启动介质选择、加载内核与设备树。i.MX8/8M/9系列还涉及SCU(System Controller Unit)固件和ATF(Arm Trusted Firmware)。
  • Linux Kernel:基于NXP维护的linux-imx分支,包含i.MX专用驱动(如VPU、GPU、ENET、USDHC、I2C、SPI、PCIe等)。
  • Device Tree:描述板级硬件资源,包括引脚复用、时钟、电源域、外设地址与中断。同一SoC不同板卡通过不同.dts文件区分。
  • Rootfs:由Yocto生成,包含BusyBox、systemd、库文件、测试工具和NXP专有固件。
  • Yocto Metadata:包括meta-imx、meta-freescale、meta-freescale-distro、meta-openembedded等Layer,以及bblayers.conf、local.conf、machine配置。
  • 工具链与镜像:交叉编译器、imx-image-full、imx-image-multimedia等预置镜像。

这些组件并非孤立存在,而是通过Yocto的配方(Recipe)和Layer机制组织在一起。下图展示了i.MX Linux BSP的典型组成与源码树结构关系:

i.MX Linux BSP 组成与源码树结构 Yocto 构建系统(BitBake + Layer 机制) meta-imx meta-freescale meta-openembedded meta-bsp-custom poky U-Boot / ATF / SCFW • SPL / DDR 初始化 • 启动介质选择(eMMC/SD/QSPI) • 加载 Kernel + DTB + Ramdisk • 环境变量与启动脚本 Linux Kernel (linux-imx) • 板级 DTS / DTSI • 驱动:ENET / USDHC / I2C / SPI • VPU / GPU / PCIe / USB • 电源域与时钟树配置 Rootfs 与镜像 • imx-image-full / core-image • BusyBox / systemd • NXP 专有固件与库 • 测试工具与示例程序 i.MX 硬件平台(SoC + 板级外设) CPU 核心 DDR eMMC / SD 以太网 PHY USB / PCIe 显示 / 摄像头 PMIC 硬件适配在 BSP 中的位置 ① 引脚复用 (IOMUXC) ② 时钟与电源域 ③ 设备树节点与属性 ④ 驱动匹配与初始化 硬件适配贯穿 U-Boot、Kernel 与 Rootfs 三层,核心输出为设备树与板级配置文件 示例结构基于 NXP i.MX8M Plus EVK 与 Yocto Kirkstone 版本,实际路径以 BSP Release 为准

二、Yocto与源码树结构

Yocto Project并非一个单一的Linux发行版,而是一套构建框架。它通过BitBake解析Recipe(.bb文件),按照Layer优先级合并配置,最终生成可烧录的镜像。i.MX BSP的源码树通常包含以下关键目录:

imx-yocto-bsp/
├── sources/
│   ├── poky/                  # Yocto 基础层
│   ├── meta-imx/              # NXP i.MX 专用层
│   │   ├── meta-bsp/          # 板级支持(U-Boot、Kernel、DTS)
│   │   ├── meta-sdk/          # SDK 与工具链
│   │   └── meta-vip/          # 多媒体与视觉
│   ├── meta-freescale/        # Freescale/NXP 通用层
│   ├── meta-freescale-distro/ # 发行版配置
│   └── meta-openembedded/     # 通用开源软件包
├── build/                     # 构建输出目录
│   ├── conf/
│   │   ├── bblayers.conf      # 启用的 Layer 列表
│   │   └── local.conf         # 机器、镜像、并行度配置
│   └── tmp/deploy/images/     # 最终镜像与 DTB
└── imx-setup-release.sh       # 环境初始化脚本

其中,meta-imx/meta-bsp/recipes-bsp/u-boot/存放U-Boot配方与补丁,meta-imx/meta-bsp/recipes-kernel/linux/存放内核配方与设备树。板级适配通常以.bbappend文件形式追加,避免直接修改原厂Recipe。

三、硬件适配在BSP中的位置

硬件适配的本质是“让软件知道硬件长什么样”。在i.MX BSP中,这一工作主要落在三个层面:

  1. U-Boot层:配置DDR参数、引脚复用、启动介质顺序、PMIC电压。例如在board/freescale/imx8mp_evk/下修改spl.c和imx8mp_evk.c。
  2. Kernel层:编写或修改设备树,描述I2C地址、SPI片选、GPIO方向、中断触发方式、时钟频率。例如为新增的传感器添加&i2c3 { sensor@48 { compatible = "vendor,sensor"; reg = <0x48>; }; };。
  3. Rootfs层:添加固件、校准文件、初始化脚本或专有库。例如Wi-Fi模组的brcmfmac43455-sdio.bin需放入/lib/firmware/brcm/。

判断适配是否成功,通常观察:U-Boot能否打印DDR容量与启动介质;内核启动日志中dmesg | grep -i i2c是否出现设备注册;/sys/class/下是否生成对应设备节点;以及实际功能(如网口ping通、屏幕点亮)是否正常。

四、学习路线与实验环境搭建

建议的学习路线为:先跑通官方EVK镜像,再修改设备树点亮一个LED或读取一个I2C传感器,最后尝试裁剪内核与添加自定义Recipe。实验环境推荐Ubuntu 20.04/22.04 LTS,至少16GB内存、250GB SSD,并安装以下依赖:

sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential \
  chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils \
  iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \
  pylint xterm zstd liblz4-tool file locales

获取BSP并初始化构建环境:

repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-kirkstone -m imx-5.15.71-2.2.0.xml
repo sync
DISTRO=fsl-imx-xwayland MACHINE=imx8mp-lpddr4-evk source imx-setup-release.sh -b build-imx8mp
bitbake imx-image-full

构建完成后,镜像位于tmp/deploy/images/imx8mp-lpddr4-evk/,使用uuu或dd烧录至SD卡即可启动。首次构建约需2~4小时,后续增量编译会显著加快。

提示:若仅需验证设备树修改,可单独编译内核与DTB:bitbake -c compile -f linux-imx,再替换SD卡中的imx8mp-evk.dtb,无需全量重建镜像。
注意:不同i.MX型号的BSP Release与Yocto版本对应关系不同。i.MX6/7常用Zeus或Dunfell,i.MX8/9推荐Kirkstone或更新版本。混用Layer可能导致编译失败或启动异常。