NXP官方开发板 uboot 编译测试
查找配置文件并编译
我们先在uboot中找到参考的开发平台,一般是原厂的开发板,参考原厂开发板的uboot移植到我们的开发板上。
方便起见,我们编写如下图所示的make.sh文件
1 | make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean |
如下图所示,NXP官方编译成功,但是这些文件是 NXP 官方 I.MX6ULL EVK 开发板。能不能用到正点原子的 I.MX6ULL 开发板上呢?让我们做一下方案验证。

烧写验证和驱动测试
将NXP官方bin文件烧录至SD卡中并插入开发板启动。

由图3可以看出,U-Boot虽然正常启动,但是有些设备会识别失败,移植就是为了让这些设备可以识别正确。我们现在依次检查各个设备是否正常。
检查存储设备

通过输入mmc设备命令检查EMMC和SD卡都正常。

网络驱动和LCD
从图 2 中可以看出:以太网驱动和LCD都初始化失败。那么接下来我们就分析原因并移植其到我们的开发板上。
在 U-Boot 中添加自己的开发板
添加开发板默认配置文件
先在 configs 目录下创建默认配置文件,复制 mx6ull_14x14_evk_emmc_defconfig,然后重命名为 mx6ull_alientek_emmc_defconfig,并做以下改动
1 | CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK" |
添加开发板对应的头文件
在目录 include/configs 下添加 I.MX6ULL-MINI 开发板对应的头文件,复制 include/configs/mx6ulevk.h,并重命名为 mx6ull_alientek_emmc.h。完成后改头文件定义。mx6ull_alientek_emmc.h 里面有很多宏定义,这些宏定义基本用于配置 uboot,也有一些 I.MX6ULL 的配置项目。如果我们自己要想使能或者禁止 uboot 的某些功能,那就在 mx6ull_alientek_emmc.h 里面做修改即可。 mx6ull_alientek_emmc.h 里面的内容比较多。
1 |
| 宏 | 作用 | 说明 |
|---|---|---|
#include <configs/mx6_common.h> |
引入 i.MX6 系列公共配置 | 很多“你没写但生效”的宏就在这里 |
PHYS_SDRAM_SIZE |
DRAM 总大小 | 必须和板子实际 DDR 容量一致 |
CONFIG_DISPLAY_CPUINFO |
启动时打印 CPU 信息 | CPU: Freescale i.MX6ULL ... |
CONFIG_DISPLAY_BOARDINFO |
启动时打印板子信息 | Board: MX6ULL ... |
CONFIG_SYS_MALLOC_LEN |
malloc 内存池大小 | U-Boot 动态内存,常见 8–16MB |
CONFIG_NR_DRAM_BANKS |
DRAM bank 数量 | i.MX6ULL 只有 1 个 |
PHYS_SDRAM |
DRAM 物理起始地址 | 固定 0x80000000 |
CONFIG_SYS_SDRAM_BASE |
DRAM 起始地址 | 通常等于 PHYS_SDRAM |
CONFIG_BOARD_EARLY_INIT_F |
使能 board_early_init_f() |
串口 / pinmux 早期初始化 |
CONFIG_BOARD_LATE_INIT |
使能 board_late_init() |
环境变量 / 外设后期处理 |
CONFIG_MXC_UART |
使能 i.MX 串口驱动 | |
CONFIG_MXC_UART_BASE |
串口寄存器基地址 | UART1 = 0x02020000 |
CONFIG_SYS_FSL_ESDHC_ADDR |
ESDHC 寄存器基地址 | eMMC / SD 控制器 |
CONFIG_SYS_FSL_USDHC_NUM |
USDHC 控制器数量 | 无 NAND 时通常为 2 |
CONFIG_SYS_MMC_ENV_DEV |
默认 MMC 设备 | eMMC 常为 USDHC2 |
CONFIG_SYS_MMC_ENV_PART |
环境变量分区 | 默认 0 |
CONFIG_CMD_I2C |
使能 i2c 命令 | i2c probe |
CONFIG_SYS_I2C_SPEED |
I2C 总线速度 | 常用 100k / 400k |
CONFIG_SYS_I2C_SLAVE |
默认从地址 | |
CONFIG_NAND_MXS |
使能 GPMI NAND | |
CONFIG_MTD_PARTITIONS |
NAND 分区机制 | |
CONFIG_MTDIDS_DEFAULT |
MTD 设备名 | |
CONFIG_MTDPARTS_DEFAULT |
NAND 分区布局 | |
CONFIG_ENV_SIZE |
env 大小 | eMMC 常 8KB |
CONFIG_ENV_OFFSET |
env 偏移地址 | 相对存储器起始 |
CONFIG_EXTRA_ENV_SETTINGS |
默认环境变量 | bootargs / bootcmd |
CONFIG_MFG_ENV_SETTINGS |
量产工具环境变量 | MfgTool 使用 |
CONFIG_BOOTCOMMAND |
默认 bootcmd | 自动启动 Linux |
CONFIG_SYS_LOAD_ADDR |
kernel 加载地址 | 常用 0x80800000 |
CONFIG_LOADADDR |
同上 | |
CONFIG_SYS_INIT_RAM_ADDR |
OCRAM 起始地址 | 0x00900000 |
CONFIG_SYS_INIT_RAM_SIZE |
OCRAM 大小 | 128KB |
CONFIG_SYS_INIT_SP_OFFSET |
初始 SP 偏移 | |
CONFIG_SYS_INIT_SP_ADDR |
初始 SP 地址 | |
CONFIG_SYS_HZ |
系统 tick | 1000Hz |
CONFIG_STACKSIZE |
栈大小 | 128KB |
CONFIG_FEC_MXC |
使能 FEC 网卡 | |
CONFIG_FEC_ENET_DEV |
使用哪个 ENET | 0=ENET1 |
IMX_FEC_BASE |
ENET 寄存器基地址 | |
CONFIG_FEC_MXC_PHYADDR |
PHY 地址 | 必须匹配硬件 |
CONFIG_FEC_XCV_TYPE |
PHY 接口类型 | RMII / RGMII |
CONFIG_CMD_DHCP |
dhcp 命令 | |
CONFIG_CMD_PING |
ping 命令 | |
CONFIG_VIDEO |
使能 LCD | |
CONFIG_VIDEO_LOGO |
显示 logo | |
CONFIG_CMD_BMP |
bmp 显示命令 |
mx6ull_alientek_emmc.h ≠ 配置全集,真正的实现分散在mx6_common.h、arch/arm/mach-imx/、drivers/*
添加开发板对应的板级文件
创建并修改Makefile文件
uboot 中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上外设驱动文件等等。 NXP 的 I.MX 系列芯片的所有板级文件夹都存放在 board/freescale 目录下,在这个目录下有个名为 mx6ullevk 的文件夹,这个文件夹就是 NXP 官方 I.MX6ULL EVK 开发板的板级文件夹。复制 mx6ullevk,将其重命名为 mx6ull_alientek_emmc。进入 mx6ull_alientek_emmc 目录中,将其中的 mx6ullevk.c 文件重命名为 mx6ull_alientek_emmc.c。并在Makefile中做出如下修改
1 | obj-y := mx6ull_alientek_emmc.o |
修改此目录下的imximage.cfg文件
将 imximage.cfg 中的下面一句:
PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000
改为:
PLUGIN board/freescale/mx6ull_alientek_emmc/plugin.bin 0x00907000
修改此目录下的 Kconfig 文件
将原文件中的原目录名改成现目录名
1 | if TARGET_MX6UL_14X14_EVK || TARGET_MX6UL_9X9_EVK |
修改此目录下的 MAINTAINERS 文件
同上述几步,也就是改成自己的文件目录
修改U-Boot图形界面配置文件
uboot 是支持图形界面配置,关于 uboot 的图形界面配置下一章会详细的讲解。修改文件 arch/arm/cpu/armv7/mx6/Kconfig(如果用的 I.MX6UL 的话,应该修改 arch/arm/Kconfig 这个文件),在 207 行加入如下内容:
1 | config TARGET_MX6ULL_ALIENTEK_EMMC |
并在最后一行的endif前加入以下内容
source "board/freescale/mx6ull_alientek_emmc/Kconfig"
到此为止, I.MX6U-MINI 开发板就已经添加到 uboot 中了,接下来就是编译这个新添加
的开发板。
使用新添加的板子配置编译uboot
编写如下脚本,运行
1 | make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean |


由图可见,此时的 Board 还是“MX6ULL 14x14 EVK”,因为我们参考的 NXP 官方的 I.MX6ULL 开发板来添加自己的开发板。前面已经说了,默认 uboot 中的 LCD 驱动和网络驱动在正点原子的 I.MX6U-MINI 开发板上是有问题的,需要修改。
网口驱动修改
正点原子的 I.MX6U-MINI 开发板ENET 网口使用 SR8201F 作为 PHY 芯片。NXP 官方的 I.MX6ULL EVK 开发板使用 KSZ8081 这颗 PHY 芯片, SR8201F 相比 KSZ8081 具有体积小、外围器件少、价格便宜等优点。直接使用 KSZ8081 固然可以,但是我们在实际的产品中不一定会使用 KSZ8081,有时候为了降低成本会选择其他的 PHY 芯片,这个时候就有个问题:换了 PHY 芯片以后网络驱动怎么办?为此,正点原子的 I.MX6U-ALPHA 开发板将 ENET1 和 ENET2的 PHY 换成了 SR8201F,这样就可以给大家讲解更换 PHY 芯片以后如何调整网络驱动,使网络工作正常。

ENET1 的网络 PHY 芯片为 SR8201F,通过 RMII 接口与 I.MX6ULL 相连,正点原子 I.MX6U-ALPHA 开发板的 ENET1 引脚与 NXP 官方的 I.MX6ULL EVK 开发板基本一样,唯独复位引脚不同。从图 33.2.8.1 可以看出,正点原子 I.MX6U-ALPHA 开发板的 ENET1 复位引脚 ENET1_RST 接到了 I.M6ULL 的 SNVS_TAMPER7 这个引脚上。
SR8201F 内部是有寄存器的, I.MX6ULL 会读取 SR8201F 内部寄存器来判断当前的物理链接状态、连接速度(10M 还是 100M)和双工状态(半双工还是全双工)。 I.MX6ULL 通过 MDIO 接口来读取 PHY 芯片的内部寄存器, MDIO 接口有两个引脚, ENET_MDC 和 ENET_MDIO, ENET_MDC 提供时钟, ENET_MDIO 进行数据传输。一个 MDIO 接口可以管理 32 个 PHY 芯片,同一个 MDIO 接口下的这些 PHY 使用不同的器件地址来做区分, MIDO 接口通过不同的器件地址即可访问到相应的 PHY 芯片。 I.MX6U-ALPHA 开发板 ENET1 上连接的 SR8201F 器件地址为 0X2,所示我们要修改 ENET1 网络驱动的话重点就三点:
①、 ENET1 复位引脚初始化。
①、 ENET1 复位引脚初始化。
③、 SR8201F 驱动
网络 PHY 地址修改
首先修改 uboot 中的 ENET1 和 ENET2 的 PHY 地址和驱动,打开 mx6ull_alientek_emmc.h这个文件,找到如下代码:
1 |
①、修改 ENET1 网络 PHY 的地址。
②、修改 ENET2 网络 PHY 的地址。
③、使能 REALTEK 公司的 PHY 驱动。
1 |
删除74LV595的驱动代码
打开mx6ull_alientek_emmc.c,将以下代码替换:
1 | //替换前 |
删掉static iomux_v3_cfg_t const iox_pads[]配置,删除iox74lv_init、iox74lv_set函数,并在board_init函数中将他们的调用删除。
添加 I.MX6U-ALPHA 开发板网络复位引脚驱动
结构体数组 fec1_pads 和 fec2_pads 是 ENET1 和 ENET2 这两个网口的 IO 配置参数,在这两个数组中添加两个网口的复位 IO 配置参数,完成以后如下所示
1 | static iomux_v3_cfg_t const fec1_pads[] = { |
函数 setup_iomux_fec 就是根据 fec1_pads 和 fec2_pads 这两个网络 IO 配置数组来初始化 I.MX6ULL 的网络 IO。我们需要在其中添加网络复位 IO 的初始化代码,并且复位一下 PHY 芯片,修改后的 setup_iomux_fec 函数如下
1 | static void setup_iomux_fec(int fec_id) |
fec1_pads 就是“ENET1 要用到的每个脚,该怎么复用、该用什么电气参数”的清单.imx_iomux_v3_setup_multiple_pads函数的作用是把一组 pad(引脚)的 IOMUX + PAD 控制配置批量写进 IOMUXC 寄存器。
编译后烧录:

在uboot使用网络之前先要设置几个环境变量
setenv ipaddr 192.168.1.55 //开发板 IP 地址
setenv ethaddr b8:ae:1d:01:00:00 //开发板网卡 MAC 地址
setenv gatewayip 192.168.1.1 //开发板默认网关
setenv netmask 255.255.255.0 //开发板子网掩码
setenv serverip 192.168.1.250 //服务器地址,也就是 Ubuntu 地址 saveenv //保存环境变量
LCD
主播手上没有LCD屏幕,因此这一部分暂时不做。
结语
至此,I.MX6ULL 平台下 U-Boot 板级移植的完整流程已经走通。从最初复制 NXP 官方 EVK 的板级代码,到创建新的 defconfig、Kconfig、board 目录,再到逐步调试 LCD 和以太网驱动,整个过程并非简单的“改文件名 + 改宏定义”,而是一次对 U-Boot 架构理解的系统性实践。后续还会做RK3588平台的驱动实战。