i.MX6ULL移植内核6.6(一)修改网络驱动和LCD驱动
本篇主要内容
- 一、准备工作
- 1.1 环境准备
- 1.2 NXP源码初次编译
- (1)修改Makefile
- (2)NXP的相关源文件
- (3)编译和启动测试
- 二、修改SR8201F网络驱动
- 2.1 SR8201F连接原理图
- 2.2 修改设备树
- 三、修改LCD驱动
- 3.1 LCD连接原理图
- 3.2 LCD时序参数含义
- 3.3 设备树定义
- (1)数据引脚定义
- (2)控制引脚定义
- (3)lcd节点定义
- 3.4 编译烧写测试
一、准备工作
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小节
✅源码包:lf-6.6.y.zip
NXP官方github链接,建议用迅雷下载
1.2 NXP源码初次编译
(1)修改Makefile
(2)NXP的相关源文件
📌这里有必要先了解一下NXP适配其i.MX6ULL开发板(官板/评估板)的一些配置和源文件,后面在这些文件的基础上修改,适配到我们的目标开发板
📂配置文件:arch/arm/configs/imx_v7_defconfig
📂设备树: arch/arm/boot/dts/nxp/imx/imx6ull-14x14-evk-emmc.dts
arch/arm/boot/dts/nxp/imx/imx6ull-14x14-evk.dts
arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
以上设备树都是一层一层包含的关系
(3)编译和启动测试
📌导入交叉编译器的环境变量,直接编译并用tftp加载到开发板运行(这里uboot是前面篇的uboot-2025,根文件系统先用的正点原子官方提供的)
wo002582@ubuntu2204:~/linux-imx-lf-6.6.y$ export PATH=$PATH:/opt/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf/bin
wo002582@ubuntu2204:~/linux-imx-lf-6.6.y$ make imx_v7_defconfig
wo002582@ubuntu2204:~/linux-imx-lf-6.6.y$ make -j16
📌编译完,在uboot设置从网络启动,命令如下
# 网络配置
setenv ipaddr 192.168.6.244
setenv ethaddr b8:ae:1d:01:00:00
setenv gatewayip 192.168.6.1
setenv netmask 255.255.255.0
setenv serverip 192.168.6.147
# 环境变量bootcmd和bootargs
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull-14x14-evk-emmc.dtb;bootz 80800000 - 83000000'
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.6.147:/home/wo002582/nfs/rootfs,nfsvers=3,proto=tcp rw ip=192.168.6.244:192.168.6.147:192.168.6.1:255.255.255.0::eth0:off'
savenv
📌可以看到,官板的PHY芯片是Micrel的KSZ8081系列,但本篇使用的开发板PHY芯片是SR8201F,由于网络的原因挂载不了nfs的根文件系统,此时如果挂载到emmc的根文件系统是可以的,这里就不记录了。当务之急是适配好网络驱动,
二、修改SR8201F网络驱动
2.1 SR8201F连接原理图
2.2 修改设备树
📌这里修改的设备树是arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
配置修改和前面移植uboot-2025一样,添加上fec节点和复位引脚即可,数据引脚和原来一致,最后主要将GPIO5_IO7和GPIO5_IO8作为复位引脚的占用注释掉。详细版本可见:i.MX6ULL开发板uboot-2025移植(修改SR8201F网络驱动和LCD驱动),修改好设备树后,驱动已默认使能,只需要重新编译内核和设备树即可。
/* fec节点 */
&fec1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_enet1&pinctrl_enet1_reset>; phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>; phy-mode = "rmii"; phy-handle = <ðphy1>; local-mac-address = [00 0a 35 00 00 01]; phy-reset-post-delay = <200>; 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 {#address-cells = <1>;#size-cells = <0>;ethphy1: ethernet-phy@2 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0x02>; };ethphy2: ethernet-phy@1 {compatible = "ethernet-phy-ieee802.3-c22";reg = <0x01>;};};
};/* 复位引脚 */pinctrl_enet1_reset: enet1resetgrp {fsl,pins = <MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0>;};pinctrl_enet2_reset: enet2resetgrp {fsl,pins = <MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0>;};
三、修改LCD驱动
3.1 LCD连接原理图
3.2 LCD时序参数含义
屏幕参数 | 设备树参数 | 缩写 | 含义 |
---|---|---|---|
Vertical Dislplay Area / Horizontal Display Area | vactive / hactive | _ | 垂直活跃像素宽度 / 水平活跃像素宽度(显示区域) |
VS Front Porch / HS Front Porch | vfront-porch / hfront-porch | vfp / hfp | 垂直前肩 / 水平前肩 |
VS Blanking / HS Blanking | vback-proch / hback-porch | vbp / hbp | 垂直后肩 / 水平后肩 |
VS pulse width / HS pulse width | vsync-len / hsync-len | vspw / hspw | 垂直同步信号宽度 / 水平同步信号宽度 |
DCLK Frequency | clock-Frequency | DCLK | 数据时钟频率 |
3.3 设备树定义
(1)数据引脚定义
📌在源码中NXP已经定义好了数据引脚,也就是原理图中R、G、B各8个共24个引脚;这里不需要修改。
pinctrl_lcdif_dat: lcdifdatgrp {fsl,pins = <MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79>;};
(2)控制引脚定义
📌同上,源码中已经定义好控制引脚(原理图粉色部分)不需要修改。
pinctrl_lcdif_ctrl: lcdifctrlgrp {fsl,pins = <MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79/* used for lcd reset */MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x79>;};
(3)lcd节点定义
📌同样这里大部分内容都已经写好,我们需要做的只是修改display中的屏幕参数,屏幕参数的来源可查询屏幕的数据手册或相关资料,比如这里使用的屏幕所提供的资料中,给定相关参数的范围。
&lcdif {assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>; /* 时钟 */assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>; /* 时钟源 */pinctrl-names = "default";pinctrl-0 = <&pinctrl_lcdif_dat&pinctrl_lcdif_ctrl>;display = <&display0>;status = "okay";display0: display@0 {bits-per-pixel = <24>; /* 像素位宽:RGB888格式1个像素24bit */bus-width = <24>; /* 总线位宽24bit数据线 */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>;};};};
};
3.4 编译烧写测试
📌最后,可以看到LCD显示的内核logo(默认内核已经开启)就说明本节的目的完成。设置一下uboot环境变量,同时可以看到LCD作为终端输出信息。