4. BSP软件架构

在 TI Sitara AM64x 的 BSP 开发中,启动链路上的四个核心组件——U-Boot、Linux 内核、设备树(Device Tree)与根文件系统(RootFS)——共同构成一个可运行、可裁剪、可量产的嵌入式 Linux 系统。理解它们的组成与相互关系,是后续移植、裁剪、调试与量产固件设计的基础。本节从启动时序、职责边界、数据传递与镜像布局四个角度展开,并给出可落地的验证方法。

一、核心原理:四件套的职责与启动时序

AM64x 上电后,片内 ROM 先加载引导介质中的第一阶段引导程序(如 tiboot3.bin),随后进入 U-Boot 的 SPL/Proper 阶段。U-Boot 完成 DDR 初始化、时钟与外设基础配置后,从存储介质读取 Linux 内核镜像与设备树,并把控制权交给内核。内核在早期初始化阶段解析设备树,完成 CPU、内存、中断控制器、串口、MMC、以太网等硬件描述,随后挂载根文件系统,启动用户态 init 进程。

四者的职责边界可以概括为:U-Boot 负责“把系统带起来”,内核负责“管理硬件与进程”,设备树负责“告诉内核硬件长什么样”,根文件系统负责“提供用户态运行环境”。它们不是并列关系,而是存在明确的依赖与传递关系:U-Boot 是加载者,内核是被加载者,设备树是内核的参数输入,根文件系统是内核启动用户态的必要条件。

AM64x BSP 启动链路与四组件关系 Boot ROM tiboot3.bin U-Boot SPL + Proper Linux 内核 Image / zImage 根文件系统 RootFS / init 设备树 DTB am64x-evm.dtb 硬件描述 内核解析 DTB → 注册 platform_device → 匹配驱动 串口 / MMC / 以太网 / I2C / SPI 等外设被枚举 存储介质布局(eMMC / SD / QSPI) tiboot3.bin | tispl.bin | u-boot.img | Image | am64x-evm.dtb | rootfs.ext4 U-Boot 负责按顺序读取并跳转,内核负责挂载 RootFS

二、方法流程:从源码到可启动镜像

在 AM64x SDK 中,四件套通常由不同源码树构建,最终通过 tisdk-image 或 create-sdcard.sh 打包到同一介质。典型构建流程如下:

  1. U-Boot 构建:配置 am64x_evm_a53_defconfig,编译生成 tiboot3.bin、tispl.bin、u-boot.img。
  2. 内核构建:使用 defconfig 或 tisdk_am64xx-evm_defconfig,生成 Image 与模块。
  3. 设备树构建:在内核源码中编译 arch/arm64/boot/dts/ti/am64x-evm.dts,生成 am64x-evm.dtb。
  4. 根文件系统构建:通过 Yocto 或 Buildroot 生成 tisdk-base-image-am64xx-evm.tar.xz,并转换为 ext4 镜像。
  5. 打包与烧录:将上述文件按分区写入 SD 卡或 eMMC,设置 boot 分区与 rootfs 分区。
# 典型 U-Boot 环境变量(AM64x EVM)
setenv bootargs "console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext4"
setenv bootcmd "mmc dev 0; fatload mmc 0:1 0x82000000 Image; fatload mmc 0:1 0x88000000 am64x-evm.dtb; booti 0x82000000 - 0x88000000"
saveenv

上述 bootargs 中的 root= 与 rootfstype= 直接决定内核如何挂载根文件系统;booti 的第三个参数即设备树地址。若设备树地址错误或 DTB 与内核版本不匹配,常见现象是内核启动到 Uncompressing Linux... 后卡死,或串口无输出。

三、案例场景:设备树如何影响外设可用性

以 AM64x EVM 上的 CPSW3G 以太网为例,若设备树中 cpsw3g 节点的 status 为 "disabled",则内核不会注册该平台设备,即使 U-Boot 已初始化 PHY,Linux 下也看不到 eth0。反之,若设备树中 phy-mode 配置为 "rgmii" 而硬件实际为 "rgmii-id",则链路可能协商成功但丢包严重。这说明设备树不是“可选项”,而是内核识别硬件的唯一权威描述。

设备树与内核版本强相关。升级内核时,必须同步更新 DTB,否则可能出现节点属性不识别、驱动 probe 失败等问题。建议在 U-Boot 中通过 fdt addr 与 fdt print 先验证 DTB 是否可解析。

四、误区与复盘:常见错误与排查清单

初学者常把根文件系统与内核混为一谈,认为“内核启动完成系统就能用”。实际上,内核启动到最后会执行 /sbin/init,若根文件系统缺失或 init 不存在,内核会报 Kernel panic - not syncing: No init found。另一个常见误区是忽略 U-Boot 与内核的镜像格式差异:ARM64 通常使用 booti 加载 Image,而 ARM32 使用 bootz 加载 zImage,用错命令会导致“Starting kernel ...”后无输出。

组件 典型文件 核心职责 常见故障现象
U-Boot tiboot3.bin / tispl.bin / u-boot.img 初始化 DDR、加载内核与 DTB 串口无输出、卡在 SPL
Linux 内核 Image 管理硬件、进程、内存与驱动 Starting kernel 后卡死
设备树 am64x-evm.dtb 描述硬件资源与连接关系 外设缺失、驱动 probe 失败
根文件系统 rootfs.ext4 / init 提供用户态工具与 init 进程 Kernel panic: No init found
排查启动问题时,建议按“U-Boot → 内核 → 设备树 → 根文件系统”的顺序逐段确认:先看 U-Boot 能否进入命令行,再看内核是否解压并打印 Booting Linux,然后确认 DTB 是否被正确加载,最后检查 root= 指向的分区是否存在且可挂载。

综上,AM64x BSP 的四件套是一个有明确先后与依赖关系的整体:U-Boot 是引导者,内核是执行者,设备树是描述者,根文件系统是用户态载体。只有四者版本匹配、地址正确、参数一致,系统才能稳定启动并进入可开发状态。