i.MX6ULL开发板uboot-2025移植(修改SR8201F网络驱动和LCD驱动)
本篇主要内容:
一、准备工作
1.1 环境准备
✅开发板:正点原子i.IMX6ULL阿尔法开发板
✅虚拟机:ubuntu22.04(太低会遇到openssl相关的报错,例如16.04)
✅编译器:gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf编译器选择没有特别的,在arm官网下载,下载选择可参考
第八篇 交叉编译华为云Iot SDK到Orangepi3B 1.1小节
✅源码包:uboot-imx-lf_v2025.04
NXP官方链接
1.2 源码初次编译和烧写
(1)安装交叉编译器
sudo tar -xvf gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf.tar.xz -C /opt/ # 这里解压到/opt目录
export PATH=$PATH:/opt/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf/bin # 这里选择临时添加环境变量的方式
(2)下载源码和安装依赖库
git clone https://github.com/nxp-imx/uboot-imx.git
sudo apt-get install libgnutls28-dev #没有这个库编译会报以下的错

(3)Makefile声明ARCH和CROSS_COMPILE
⚠️如图,将273行注释,直接添加以下内容
(3)初次编译和烧写
⚠️在这里我们能找到NXP的mx6ull开发板的配置configs/mx6ull_14x14_evk_emmc_defconfig,先使用这个配置进行编译
wo002582@ubuntu2204:~/uboot-imx-lf_v2025.04$ export PATH=$PATH:/opt/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf/bin
wo002582@ubuntu2204:~/uboot-imx-lf_v2025.04$ make mx6ull_14x14_evk_emmc_defconfig
HOSTCC scripts/kconfig/conf.o
YACC scripts/kconfig/zconf.tab.c
LEX scripts/kconfig/zconf.lex.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#
wo002582@ubuntu2204:~/uboot-imx-lf_v2025.04$ make -j16
⚠️编译完成,可以得到u-boot.bin,使用正点原子的工具imxdownloader烧写到SD卡启动后,可以看到在阿尔法IMX6ULL开发板上可以运行,只是有一些小问题

二、添加网络驱动
以下内容均在nxp官板配置和相关源文件上修改,为了方便不再重新拷贝/重命名官板文件
2.1 NXP官板的相关源文件
✅这里有必要了解一下NXP适配其官板的一些配置和源文件
📌默认配置文件:configs/mx6ull_14x14_evk_emmc_defconfig(有多个不同配置,这里用的是emmc)
📌头文件:include/configs/mx6ullevk.h
📌板级文件夹:board/freescale/mx6ullevk(freescale:飞思卡尔,NXP前身)
电源、网卡、LCD设置初始化,以及开发板初始启动的代码在mx6ullevk.c中
📌设备树文件:相关外设定义:arch/arm/dts/imx6ul-14x14-evk.dtsi,相关引脚功能定义在imx6ul-pinfunc.h
2.2 关于SR8201F
(1)MAC芯片和PHY芯片
| MAC芯片 | PHY芯片 | |
|---|---|---|
| 所属OSI层 | 数据链路层 | 物理层 |
| 主要功能 | 数据帧封装、网络寻址(MAC地址)等 | 数模信号转换、速率协商等 |
| 常见接口 | MII、GMII、RGMII等连接PHY | 通过MII、GMII、RGMII等接口连接MAC;通过mdio接口连接物理接口(如网口座子、网线) |
| 其它 | 一般集成在SOC内 | 一般是独立的 |
✅工作流程:MAC芯片将数据封装成以太网帧格式,通过MII/RMII接口把这个发送给PHY芯片,
PHY芯片对数据进行数模转换和编码,得到模拟信号通过网线发送到对端。
(2)SR8201F连接原理图
备注为up查阅资料后自行添加,可能有误仅供参考
2.3 添加SR8201F驱动
✅从原理图可以看到,使用SR8201F需要的引脚大致就RMII蓝色部分和复位引脚红色部分。在设备树下定义和含义如下:
pinctrl_enet2: enet2grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0 /* mdio时钟 */
MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0 /* mdio数据线 */
MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0 /* 接收使能引脚(接MAC) */
MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0 /* 接收错误信号引脚(接MAC) */
MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0 /* 接收数据0 */
MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0 /* 接收数据1 */
MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0 /* 发送使能引脚 */
MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0 /* 发送数据0 */
MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0 /* 发送数据1 */
MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031 /* 时钟输入引脚,由PHY或外部晶振提供50MHz时钟给MAC */
>;
};
✅引脚功能复用声明可在imx6ul-pinfunc.h中查找
(1)数据引脚定义
✅在arch/arm/dts/imx6ul-14x14-evk.dtsi中定义好了ENET1和ENET2的RMII接口部分的引脚,这里是官板原来已经写好的,不需要修改或添加。引脚的含义可见上面注释。
pinctrl_enet1: enet1grp {
fsl,pins = <
MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
>;
};
pinctrl_enet2: enet2grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
>;
};
✅这里可能会有疑问:为什么pinctrl_enet1节点没有定义MDC和MDIO相关引脚呢?经过up测试,如果加上反而会读取不到PHY地址。查阅资料后,给出的解释是:i.MX6ULL芯片设计时,就将MDIO管理总线默认分配给了FEC1,也就是FEC1硬件上默认接到的MDIO总线,而FEC2则需要使用GPIO复用MDIO和MDC功能的引脚。
(2)复位引脚定义
✅这里是需要手动添加的,使用的是GPIO5的IO07和IO08引脚,由于前面这两个引脚被使用了,所以需要将imx6ul-14x14-evk.dtsi中关于GPIO5_IO07和GPIO5_IO08的内容注释掉,修改如图所示:
pinctrl_enet1_reset: enet1resetgrp {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
>;
};
pinctrl_enet2_reset: enet2resetgrp {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
>;
};



(3)fec节点定义
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1
&pinctrl_enet1_reset>; /* 数据引脚和复位引脚 */
phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>; /* 复位引脚:低电平有效 */
phy-mode = "rmii"; /* 接口类型RMII */
phy-handle = <ðphy1>; /* mdio句柄 */
local-mac-address = [00 0a 35 00 00 01]; /* mac地址 */
phy-reset-post-delay = <200>; /* 复位后延时200ms,SR8201F要求 */
status = "okay";
};
&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2
&pinctrl_enet2_reset>;
phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
phy-mode = "rmii";
phy-handle = <ðphy2>;
local-mac-address = [00 0a 35 00 00 02];
phy-reset-post-delay = <200>;
status = "okay";
/* mdio节点定义 */
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethphy1: ethernet-phy@2 { /* phy地址0x02,可见原理图 */
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x02>; /* 对应前面phy地址 */
};
ethphy2: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x01>;
};
};
};
(4)使能SR8201F驱动
✅驱动使用的Realtek RTL8201F驱动,源码路径是drivers/net/phy/realtek.c,在menuconfig配置菜单的路径是Device Drivers > Ethernet PHY (physical media interface) support > Realtek Ethernet PHYs support,选择后记得save保存。
三、编译、烧写和测试
3.1 uboot网络测试
✅这里可以顺便在menuconfig中添加mdio命令用于测试,路径是Command line interface > Network commands
✅保存重新编译uboot,烧写到SD卡启动,配置IP进行测试,看到如图的结果就完成了本篇的目的了

✅注意上面会默认使用ENET2,也就是开发板上靠近COM3的网口,如果想切换到ENET1,需要设置ethact这个环境变量,如:setenv ethact eth0。
3.2 uboot启动内核测试
✅完成了上面的内容后,用其下载内核镜像和挂载根文件系统进行测试,可以看到以下报错:
✅解决方法如下图所示:找到imx6ull.dtsi的epdc节点,将arch/arm/mach-imx/mx6/module_fuse.c中匹配改属性的值改成fsl,imx7d-edpc。保存重新编译烧写即可。

✅最后,设置好环境变量,启动系统测试

四、添加LCD驱动(7’1024x600 RGB屏幕)
✅nxp已经配置好了设备树,这里只需要在lcdif修改屏幕参数即可,以下是7寸1024x600分辨率的屏幕参数。修改后,重新编译,烧写uboot,启动后在uboot可以看到NXP的logo
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
display = <&display0>;
status = "okay";
display0: display@0 {
bits-per-pixel = <24>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <51200000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hback-porch = <140>;
hsync-len = <20>;
vback-porch = <20>;
vfront-porch = <12>;
vsync-len = <3>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};

更多推荐
所有评论(0)