4. U-Boot移植与板级适配

U-Boot 是 i.MX 平台从上电到进入 Linux 内核之间的关键引导固件,它负责最早期时钟与 DDR 初始化、串口控制台输出、镜像加载与启动参数传递。把 NXP 官方 EVK 的 U-Boot 移植到一块自研 i.MX6ULL 板卡上,本质上是围绕“板级目录、defconfig、设备树、DDR 参数、时钟与引脚复用、串口与网络驱动”这几条主线做适配,最后通过编译产物和烧录启动来验证。本节以一块典型的 i.MX6ULL 自研板(512MB DDR3L、单网口、调试串口 UART1)为例,说明移植过程中真正需要动手修改的对象和判断依据。

board 目录结构与 defconfig 的对应关系

U-Boot 源码中与板级适配最直接相关的是 board/freescale/、arch/arm/mach-imx/、configs/ 和 arch/arm/dts/ 四个位置。板级目录存放板卡专属的初始化代码,例如 board/freescale/mx6ull_myboard/mx6ull_myboard.c,其中通常包含 board_init()、dram_init()、board_late_init() 等函数;configs/mx6ull_myboard_defconfig 决定编译时启用哪些驱动和功能;设备树文件 arch/arm/dts/mx6ull-myboard.dts 描述硬件资源;arch/arm/dts/Makefile 和 configs/ 中的条目则把三者关联起来。

移植的第一步通常是复制参考板目录并重命名。例如以 mx6ull_14x14_evk 为模板:

cp -a board/freescale/mx6ull_14x14_evk board/freescale/mx6ull_myboard
cp configs/mx6ull_14x14_evk_defconfig configs/mx6ull_myboard_defconfig
cp arch/arm/dts/imx6ull-14x14-evk.dts arch/arm/dts/imx6ull-myboard.dts

随后修改 board/freescale/mx6ull_myboard/Kconfig 中的 TARGET_MX6ULL_MYBOARD、MAINTAINERS 以及 board/freescale/mx6ull_myboard/Makefile 里的目标名,使 make mx6ull_myboard_defconfig 能正确匹配。defconfig 中需要重点确认的配置项包括:CONFIG_TARGET_MX6ULL_MYBOARD=y、CONFIG_DEFAULT_DEVICE_TREE="imx6ull-myboard"、CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_myboard/imximage.cfg",以及串口、MMC、FEC 网络等驱动开关。defconfig 不是“越全越好”,而是按板卡实际外设裁剪,避免编译出无法启动的镜像。

i.MX6ULL U-Boot 板级适配关系图 源码结构 board/freescale/ mx6ull_myboard/ configs/ mx6ull_myboard_defconfig arch/arm/dts/ imx6ull-myboard.dts arch/arm/mach-imx/ mx6ull/ 时钟与DDR include/configs/ mx6ull_myboard.h 板级适配动作 复制参考板目录并重命名 Kconfig / Makefile / MAINTAINERS 修改 defconfig 目标与驱动 TARGET / DTS / 串口 / FEC 编写板级设备树 UART1 / FEC / MMC / pinctrl DDR 初始化参数 DDR3L 512MB / 校准 时钟与引脚复用 CCM / IOMUXC / GPR 串口与网络驱动适配 UART1 控制台 / FEC 网口 编译与烧录验证 make mx6ull_myboard_defconfig 生成 .config make -j4 u-boot.bin / u-boot.imx 烧录到 SD / eMMC dd 或 mfgtool 串口控制台输出 U-Boot 版本 / DRAM 容量 网络与启动验证 ping / tftp / bootz

设备树与 DDR 初始化

U-Boot 阶段的设备树与内核设备树可以共用一份,也可以单独精简。对 i.MX6ULL 而言,U-Boot 设备树至少要让串口、MMC、FEC 和 pinctrl 可用。以 UART1 为例,需要在 imx6ull-myboard.dts 中确认:

&uart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart1>;
    status = "okay";
};

&pinctrl_uart1 {
    fsl,pins = <
        MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
        MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
    >;
};

DDR 初始化是移植中最容易“卡死”的环节。i.MX6ULL 的 DDR 控制器参数通常由 NXP 提供的 MX6ULL_DDR3_512MB 脚本或 ddr_init 表生成,核心参数包括 MMDC_MDCTL、MMDC_MDCFG0、MMDC_MDCFG1、MMDC_MDMISC、MMDC_MPRDDLCTL 等。若板卡 DDR 容量、位宽或时序与参考板不同,必须用 NXP 的 DDR Stress Test 工具重新校准,得到一组可用的 ddr_init 值,再写入 board/freescale/mx6ull_myboard/ddr_init.c 或对应的 imximage.cfg。判断 DDR 是否初始化成功,最直接的依据是串口打印的 DRAM: 512 MiB 是否与实际容量一致;若打印为 0 MiB 或直接复位,应优先检查 DDR 供电、VREF、时钟和校准参数。

时钟与引脚复用

i.MX6ULL 的时钟由 CCM 模块管理,U-Boot 启动阶段会按 imx6ull-clock.c 中的 PLL 配置建立 ARM、AHB、IPG、UART、FEC 等时钟。板级适配时通常不需要大改 PLL,但要确认 CONFIG_SYS_MX6_HCLK、CONFIG_SYS_MX6_CLK32 等宏与晶振一致。若使用 24MHz 晶振,而参考板为 32.768kHz,则必须同步修改,否则串口波特率会出现明显偏差。

引脚复用通过 IOMUXC 完成。每个引脚需要选择 ALT 功能并设置电气属性,例如 UART1_TX 选择 MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX,FEC1 的 MDIO/MDC 选择 MX6UL_PAD_ENET1_MDIO__ENET1_MDIO。电气属性值 0x1b0b1 表示上拉、驱动能力中等、速度中等,实际应根据原理图和信号完整性调整。若串口无输出,先查 UART1 的 pinmux 是否被其它功能占用;若网口不通,先查 FEC 的 PHY 地址、复位引脚和时钟是否与设备树一致。

串口与网络驱动适配

串口是移植的“生命线”。在 defconfig 中确认 CONFIG_MXC_UART=y、CONFIG_CONS_INDEX=1,并在板级头文件中定义 CONFIG_MXC_UART_BASE 为 UART1_BASE。若控制台无输出,可用示波器测 UART1_TX 是否有波形,或临时把 CONFIG_BAUDRATE 改为 115200 并确认终端设置一致。

网络适配主要围绕 FEC 控制器和 PHY。设备树中需使能 &fec1,指定 phy-mode = "rmii"、phy-handle = <&ethphy1>,并在 mdio 节点下声明 PHY 地址。U-Boot 命令行下可用 ping 和 tftp 验证:

setenv ipaddr 192.168.1.100
setenv serverip 192.168.1.10
ping 192.168.1.10
tftp 0x80800000 zImage

若 ping 不通,先看 mii info 是否能读到 PHY ID;读不到通常是 MDIO 引脚复用或 PHY 地址错误,读得到但 ping 不通则检查 RMII 时钟方向、PHY 复位和网线连接。

编译与烧录验证

完成上述修改后,按以下顺序编译:

make distclean
make mx6ull_myboard_defconfig
make -j4

编译成功会生成 u-boot.bin、u-boot.imx 和 SPL(若启用)。烧录到 SD 卡时,通常将 u-boot.imx 写入偏移 1024 字节处:

sudo dd if=u-boot.imx of=/dev/sdb bs=512 seek=2 conv=fsync

上电后观察串口输出,正常应依次看到 U-Boot 版本、DRAM 容量、MMC 设备、网络 PHY 信息,并最终进入 => 提示符。此时可进一步用 mmc list、mii info、ping 逐项确认外设。若卡在 DRAM: 之后无输出,优先回查 DDR 校准参数;若进入命令行但网络不通,回查 FEC 设备树与 PHY 配置。只有串口、DDR、存储和网络都通过验证,U-Boot 移植才算真正完成,才能继续进入内核与根文件系统的适配阶段。