4. Layerscape Linux内核裁剪与设备树定制
Layerscape 系列 SoC(如 LS1046A、LS1028A、LX2160A)在出厂 BSP 中提供的 Linux 内核与设备树是"全功能"版本:它同时使能了几乎所有外设驱动、文件系统、调试选项和网络协议栈,镜像体积大、启动时间长,且包含大量目标板并不使用的节点。边缘路由平台通常资源受限、启动时间敏感,因此必须做两件事:一是通过内核配置裁剪掉无关功能,二是通过设备树精确描述本板实际存在的硬件资源。本节围绕这两条主线展开。
内核配置:从 defconfig 到最小可用集
Layerscape 内核源码位于 NXP 官方 GitHub 的 linux 仓库,常用分支如 lf-6.1.y。配置入口是 arch/arm64/configs/defconfig,它已经包含了 Layerscape 平台的基础选项。裁剪时不要直接改 defconfig,而是用 make menuconfig 生成 .config,再通过 make savedefconfig 导出精简后的 defconfig 片段,便于版本管理。
裁剪的核心判断依据是"目标板是否真的需要"。以 LS1046A 边缘路由板为例,典型裁剪方向包括:关闭 CONFIG_DEBUG_* 系列调试选项、关闭未使用的文件系统(如 CONFIG_EXT2_FS、CONFIG_NTFS_FS)、关闭 CONFIG_SOUND、CONFIG_DRM 等显示音频子系统、关闭 CONFIG_BLK_DEV_* 中不用的块设备驱动。但有几类选项必须保留:CONFIG_FSL_DPAA、CONFIG_FSL_DPAA_ETH、CONFIG_FSL_DPAA2(若使用 DPAA2)、CONFIG_FSL_QBMAN、CONFIG_FSL_PAMU,以及 CONFIG_ARM_SMMU_V3(若启用 SMMU)。这些是 DPAA 网络加速的基础,一旦裁掉,网口将无法工作。
裁剪后应验证:make Image 能成功编译,生成的 arch/arm64/boot/Image 体积明显减小(示例:从约 28 MB 降到 18 MB 左右,具体取决于配置),且启动后 dmesg 中不再出现无关驱动的探测日志。若启动失败,优先检查是否误关了 CONFIG_SERIAL_8250、CONFIG_FSL_IFC 等启动必需项。
设备树结构:从 SoC 到板级
Layerscape 设备树采用"SoC 公共部分 + 板级差异"的分层结构。以 LS1046A 为例,arch/arm64/boot/dts/freescale/ 下存在:
fsl-ls1046a.dtsi:描述 SoC 内部所有控制器,包括 CPU、内存控制器、串口、I2C、SPI、PCIe、DPAA 相关节点。fsl-ls1046a-rdb.dts:NXP 参考板设备树,#include "fsl-ls1046a.dtsi"后覆盖板级差异。- 自定义板卡设备树:通常命名为
fsl-ls1046a-myboard.dts,只写与参考板不同的部分。
这种结构的价值在于:SoC 级节点只写一次,板级文件只关心"哪些控制器被引出、地址是多少、接了什么器件"。修改时优先改板级 dts,避免动 dtsi。
CPU、内存、串口、网口节点
CPU 节点在 dtsi 中定义为 cpu@0 到 cpu@3(LS1046A 为四核 A72),每个节点包含 reg、device_type = "cpu"、enable-method = "psci"。若板卡只使用部分核心,可在板级 dts 中用 /delete-node/ 删除,或通过内核启动参数 maxcpus= 限制。
内存节点由 memory@80000000 描述,reg = <0x0 0x80000000 0x0 0x80000000> 表示从 0x80000000 起 2 GB。若板卡实际只有 1 GB,必须改为 0x40000000,否则内核会访问不存在的内存导致崩溃。
串口节点为 serial@21c0500(UART0),关键属性是 status = "okay" 和 current-speed = <115200>。调试串口必须保持 okay,否则无法看到启动日志。
网口节点分两类:MAC 控制器(如 ethernet@1d10000)和 PHY。MAC 节点中 phy-handle = <&phy0> 指向 PHY 节点,PHY 节点通过 MDIO 总线挂载,reg = <0x1> 表示 PHY 地址。若 PHY 地址接错,网口会 link down。
DPAA 相关节点
DPAA 是 Layerscape 网络加速的核心,设备树中必须正确描述以下节点:
fman@1a00000:Frame Manager,包含fsl,fman-ports、fsl,fman-muram等子节点。bman@1ac0000:Buffer Manager,管理数据缓冲区。qman@1ad0000:Queue Manager,管理帧队列。fman0-port@0等:FMan 的 MAC 端口,与ethernet节点通过fsl,fman-port关联。
这些节点的 reg 地址和中断号必须与 SoC 手册一致,通常直接沿用 dtsi 中的定义。板级只需确认 status = "okay" 以及 PHY 连接关系正确。若使用 DPAA2(如 LS1088A),则对应 fsl-mc 节点和 dpmac 节点,配置方式不同。
编译与更新
设备树编译使用 make dtbs,生成 arch/arm64/boot/dts/freescale/fsl-ls1046a-myboard.dtb。内核编译使用 make Image。两者可并行执行。
更新到目标板有三种方式:
- U-Boot 下 tftp 更新:将
Image和.dtb放到 tftp 服务器,在 U-Boot 中执行tftp 0x80000000 Image、tftp 0x90000000 fsl-ls1046a-myboard.dtb,然后booti 0x80000000 - 0x90000000启动。 - 写入 eMMC/SD:将镜像写入
/boot分区,修改extlinux.conf或 U-Boot 环境变量指向新文件。 - OTA 更新:在运行系统中通过
dd或专用工具写入备用分区,重启切换。
更新后必须验证:串口输出显示内核版本和编译时间正确、dmesg | grep -i fman 能看到 FMan 初始化成功、ip link 能看到网口且 ethtool 显示 link up。若网口未出现,优先检查设备树中 status 和 phy-handle 是否正确。
dmesg 差异,避免误删关键驱动导致启动失败。reg 时务必与板卡实际 DDR 容量一致。若声明大于实际容量,内核启动阶段可能因访问不存在内存而挂死,且现象不易定位。