从零构建i.MX6ULL定制U-Boot移植、编译与烧录实战指南当你第一次拿到i.MX6ULL开发板时最令人头疼的莫过于让这个裸板活起来。作为嵌入式系统的第一道门槛U-Boot移植往往成为新手工程师的拦路虎。本文将带你完整走通从源码获取到最终烧录的全流程针对正点原子EMMC版本开发板解决LCD驱动适配、网络配置等典型问题。1. 环境准备与源码获取在开始U-Boot移植前需要搭建完整的开发环境。不同于PC程序开发嵌入式开发对工具链的版本有严格要求。对于i.MX6ULL这类ARM Cortex-A7芯片推荐使用Linaro提供的gcc-arm-linux-gnueabihf工具链。必备工具清单交叉编译工具链gcc-arm-linux-gnueabihf建议版本7.5.0开发主机Ubuntu 18.04/20.04 LTS确保已安装libncurses5-dev终端工具minicom或picocom用于串口交互源码管理git用于获取官方U-Boot获取U-Boot源码有三种途径官方主线版本www.denx.de/wiki/U-Boot功能最新但支持有限NXP官方移植版github.com/nxp-imx/uboot-imx针对i.MX系列优化开发板厂商定制版如正点原子提供开箱即用但灵活性低对于初次移植建议从NXP官方仓库获取稳定分支git clone https://github.com/nxp-imx/uboot-imx -b lf_v2021.042. 板级文件移植与配置2.1 创建自定义板级支持包NXP官方uboot-imx已包含EVK开发板配置mx6ull_14x14_evk我们需要在其基础上创建正点原子EMMC版的专属配置。关键步骤如下复制板级配置文件cd configs/ cp mx6ull_14x14_evk_emmc_defconfig mx6ull_alientek_emmc_defconfig创建板级头文件cd include/configs/ cp mx6ullevk.h mx6ull_alientek_emmc.h移植板级驱动文件cd board/freescale/ cp -r mx6ullevk/ mx6ull_alientek_emmc cd mx6ull_alientek_emmc/ mv mx6ullevk.c mx6ull_alientek_emmc.c2.2 关键驱动适配LCD驱动修改以800x480分辨率为例 在mx6ull_alientek_emmc.h中修改显示参数#define CONFIG_VIDEO_LOGO #define CONFIG_IMX_VIDEO_SKIP #define CONFIG_SYS_WHITE_ON_BLACK struct display_info_t const displays[] {{ .bus MX6UL_LCDIF1_BASE_ADDR, .addr 0, .pixfmt 24, .detect NULL, .enable do_enable_parallel_lcd, .mode { .name ATK-LCD, .xres 800, .yres 480, .pixclock 30000, .left_margin 46, .right_margin 210, .upper_margin 23, .lower_margin 22, .hsync_len 1, .vsync_len 1, .sync 0, .vmode FB_VMODE_NONINTERLACED } } };网络PHY配置针对KSZ8081芯片 在mx6ull_alientek_emmc.c中添加复位电路控制static iomux_v3_cfg_t const phy_rst_pads[] { MX6_PAD_SNVS_TAMPER0__GPIO5_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL), }; int board_phy_config(struct phy_device *phydev) { /* 硬件复位PHY芯片 */ gpio_request(IMX_GPIO_NR(5, 0), phy_rst); gpio_direction_output(IMX_GPIO_NR(5, 0), 0); mdelay(50); gpio_set_value(IMX_GPIO_NR(5, 0), 1); /* KSZ8081特定配置 */ phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8100); phy_write(phydev, MDIO_DEVAD_NONE, 0x00, 0x1140); return 0; }3. 编译系统配置3.1 自动化编译脚本创建mx6ull_alientek_emmc.sh编译脚本#!/bin/bash # 清理工程 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- distclean # 应用默认配置 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig # 图形化配置可选 # make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- menuconfig # 多线程编译 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- V1 -j$(nproc)赋予执行权限并运行chmod x mx6ull_alientek_emmc.sh ./mx6ull_alientek_emmc.sh3.2 编译产物说明成功编译后将生成以下关键文件u-boot.bin原始二进制文件u-boot.imx带NXP特定头部的可烧录镜像u-boot.srecMotorola S-record格式u-boot.map内存映射文件调试用文件类型对比文件类型是否可烧录包含头部信息适用场景.bin否无调试分析.imx是IVTDCD生产烧录.srec是S-record串口下载4. 烧录与验证4.1 通过USB OTG烧录将开发板拨码开关设置为USB启动模式BOOT_MODE[1:0]10连接开发板OTG接口到PC使用NXP提供的mfgtools工具烧录./uuu -b emmc_all u-boot.imx4.2 通过SD卡烧录对于调试阶段推荐使用SD卡烧录方式准备FAT32格式的SD卡使用正点原子提供的imxdownload工具./imxdownload u-boot.bin /dev/sdb将拨码开关切换为SD卡启动模式BOOT_MODE[1:0]014.3 功能验证成功启动后在串口终端应看到类似输出U-Boot 2021.04 (Jun 15 2023 - 16:20:45 0800) CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz) DRAM: 512 MiB MMC: FSL_SDHC: 0, FSL_SDHC: 1 Loading Environment from MMC... OK关键测试命令mmc list查看存储设备ping 192.168.1.100测试网络连通性lcdputs hello验证LCD显示bdinfo查看板级信息5. 环境变量与启动配置5.1 网络环境设置在U-Boot命令行中配置网络参数setenv ipaddr 192.168.1.50 setenv serverip 192.168.1.100 setenv netmask 255.255.255.0 setenv gatewayip 192.168.1.1 setenv ethaddr 00:04:9f:04:d2:35 saveenv5.2 自动启动命令配置bootcmd实现自动加载内核setenv bootcmd mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000 saveenvbootargs典型配置setenv bootargs consolettymxc0,115200 root/dev/mmcblk1p2 rootwait rw6. 高级调试技巧6.1 使用TFTP加速开发主机搭建TFTP服务器sudo apt install tftpd-hpa sudo systemctl restart tftpd-hpaU-Boot中通过网络加载镜像tftp 80800000 zImage tftp 83000000 imx6ull-alientek-emmc.dtb bootz 80800000 - 830000006.2 使用JTAG调试对于复杂问题可借助J-Link或OpenOCD进行调试连接JTAG接口到开发板启动OpenOCDopenocd -f interface/jlink.cfg -f target/imx6ull.cfg使用GDB连接arm-linux-gnueabihf-gdb u-boot target remote :33336.3 常见问题排查DDR初始化失败检查board/freescale/mx6ull_alientek_emmc/中的DDR配置确认开发板DDR型号与配置匹配网络PHY不识别测量PHY芯片供电电压通常为2.5V/3.3V检查MDIO/MDC信号线连接使用mii info命令查看PHY寄存器LCD显示异常确认背光电路正常工作检查像素时钟配置使用示波器测量HSYNC/VSYNC信号时序