正点原子imx6ull开发板移植新版本U-boot(uboot2022.04,有设备树)
网络资源链接:
nxp官方仓库 ,linaro官网资源库,Ubuntu2024LTS清华镜像
参考资料:
- 详细讲解移植u-boot.2022.10版本到imx6ull开发板
- U-boot2023的移植教程
- 正点原子IMX6ULL-ALPHA开发板移植uboot2023.04
- [IMX6ULL]移植lf-v2022.04 U-boot
1. 序言
这一期记录了imx6ull的uboot移植,将nxp官方发布的uboot移植到了正点原子i.mx6ull-alpha开发板上。我做这个项目的目的在于拓展正点原子开发板uboot的开发平台范围,以及用新版的linux操作系统。因为我习惯用macbook(apple sillicon芯片)做开发。即使搭载了虚拟机,也是aarch64版本的虚拟机。但是正点原子教程中使用的老版本uboot存在以下问题:
1. 没有合适的aarch64版交叉编译器能正常编译老版本u-boot项目,因为aarch64版交叉编译器最旧的也在2020年之后了。
2. 老的u-boot仅支持nfs2,但是在ubuntu22.04之后linux内核版本5和6已经不再支持nfs2,且无法降级到4.x版本这对后续使用nfs开发造成了困扰。
也就是说,如果想用新版本的linux进行开发,就要对i.MX6ULL开发板移植新版本的u-boot。因此我对此过程进行了记录。
本期内容分为五个部分,分别是:开发环境介绍、开发准备、开发板移植、LCD驱动移植、网络驱动移植。和正点原子教程中旧版本最大的区别就在于LCD驱动移植和网络驱动移植,新版本中两者用到了设备树。
2. 开发材料介绍
- 近期ubuntu发布了24.04LTS,所以我的开发主机是ubuntu24.04操作系统的虚拟机,安装在了rog ally掌机上,这期仍然是x86平台,aarch64版本的后续再做。
- U-boot用了nxp官方仓库的imx-uboot,版本是2022.04,链接如下:https://github.com/nxp-imx/uboot-imx
- 编译器选择了和U-boot年月相近的版本,在linaro官网资源库里可以下载,我选择11.3-2022.06-1版本。
- 开发软件使用了VSCODE+Remote-SSH的方式。
3. 开发准备
a 编译一下NXP官方的imx6ullevk开发板
首先编译一下NXP官方的mx6ullevk开发板,根据提示安装各项缺失的支持包,直到编译通过为止。这里在uboot的根目录写一个bash编译脚本build-mx6ull-14x14-evk-emmc.sh,内容如下:
#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabihf- -j10
运行这个脚本,在编译过程中会提示各项缺失的库,全部安装后就能编译通过。编译成功后,能得到:u-boot.bin, u-boot.dtb, u-boot-dtb.bin, u-boot-dtb.imx四个目标文件。其功能如下:
u-boot.bin 是 U-Boot 的主要可执行文件。
u-boot.dtb 是描述硬件信息的设备树文件。
u-boot-dtb.bin 是包含了 U-Boot 和设备树的合并二进制文件。
u-boot-dtb.imx 是为 NXP i.MX 系列处理器生成的特定格式的启动镜像,包含了头部IVT DCD信息。
用正点原子开发的imxdownload工具时,只要下载u-boot-dtb.bin到sd卡即可。也可以用NXP官方的UUU工具等直接下载u-boot-dtb.imx。
b .vscode/settings.json中屏蔽无关文件
开发要改的内容有config文件夹,board文件夹,drivers文件夹,arch/arm/dts文件夹,我在settings.json中用如下代码屏蔽了无关文件
{
"search.exclude": {
"**/node_modules": true,
"**/bower_components":true,
"**/*.o":true,
"**/*.su":true,
"**/*.cmd":true,
"Documentation":true,
/* 屏蔽不用的架构相关的文件 */
"arch/alpha":true,
"arch/arc":true,
"arch/arm64":true,
"arch/avr32":true,
"arch/[b-z]*":true,
"arch/arm/plat*":true,
"arch/arm/mach-[a-h]*":true,
"arch/arm/mach-[n-z]*":true,
"arch/arm/mach-i[n-z]*":true,
"arch/arm/mach-imx/i*":true,
"arch/arm/mach-m[e-v]*":true,
"arch/arm/mach-k*":true,
"arch/arm/mach-l*":true,
/* 屏蔽排除不用的配置文件 */
"arch/arm/configs/[a-h]*":true,
"arch/arm/configs/[j-z]*":true,
"arch/arm/configs/imo*":true,
"arch/arm/configs/in*":true,
"arch/arm/configs/io*":true,
"arch/arm/configs/ix*":true,
/* 屏蔽掉不用的 DTB 文件 */
"arch/arm/boot/dts/[a-h]*":true,
"arch/arm/boot/dts/[k-z]*":true,
"arch/arm/boot/dts/in*":true,
"arch/arm/boot/dts/imx1*":true,
"arch/arm/boot/dts/imx7*":true,
"arch/arm/boot/dts/imx2*":true,
"arch/arm/boot/dts/imx3*":true,
"arch/arm/boot/dts/imx5*":true,
"arch/arm/boot/dts/imx6d*":true,
"arch/arm/boot/dts/imx6q*":true,
"arch/arm/boot/dts/imx6s*":true,
"arch/arm/boot/dts/imx6ul-*":false,
"arch/arm/boot/dts/imx6ull-9x9*":true,
"arch/arm/boot/dts/imx6ull-14x14-ddr*":true,
/*屏蔽不相关开发板*/
"board/[a-e]*":true,
"board/[g-z]*":true,
"board/[A-Z]*":true,
"board/freescale/[a-l]*":true,
"board/freescale/[n-z]*":true,
"board/freescale/m5*":true,
"board/freescale/mx6s*":true,
"board/freescale/mx7*":true,
"board/freescale/mx[1-5]*":true,
/*屏蔽不用的芯片配置文件*/
"configs/[a-l]*":true,
"configs/[n-z]*":true,
"configs/[A-Z]*":true,
"configs/m[a-w]*":true,
"configs/mx[^6]*":true,
"configs/mx6[^u]*":true,
"configs/mx6ulz*":true,
"configs/mx6ul_*":true,
/*屏蔽不用的设备树文件*/
"arch/arm/dts/[0-9]*":true,
"arch/arm/dts/[^i]*":true,
"arch/arm/dts/im[^x]*":true,
"arch/arm/dts/imx[^6]*":true,
"arch/arm/dts/imx6[^u]*":true,
"arch/arm/dts/imx6ull-[^h]*":true,
"arch/arm/dts/imx6ul-[a-z]*":true,
},
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/*.o":true,
"**/*.su":true,
"**/*.cmd":true,
"Documentation":false,
/* 屏蔽不用的架构相关的文件 */
"arch/alpha":true,
"arch/arc":true,
"arch/arm64":true,
"arch/avr32":true,
"arch/[b-z]*":true,
"arch/arm/plat*":true,
"arch/arm/mach-[a-h]*":true,
"arch/arm/mach-[n-z]*":true,
"arch/arm/mach-i[n-z]*":true,
"arch/arm/mach-m[e-v]*":true,
"arch/arm/mach-imx/i*":true,
"arch/arm/mach-k*":true,
"arch/arm/mach-l*":true,
/* 屏蔽排除不用的配置文件 */
"arch/arm/configs/[^i]*":true,
"arch/arm/configs/imo*":true,
"arch/arm/configs/in*":true,
"arch/arm/configs/io*":true,
"arch/arm/configs/ix*":true,
/* 屏蔽掉不用的 DTB 文件 */
"arch/arm/boot/dts/[a-h]*":true,
"arch/arm/boot/dts/[k-r]*":true,
"arch/arm/boot/dts/s[0-9]*":true,
"arch/arm/boot/dts/s[a-i]*":true,
"arch/arm/boot/dts/s[l-z]*":true,
"arch/arm/boot/dts/[t-z]*":true,
"arch/arm/boot/dts/in*":true,
"arch/arm/boot/dts/imx1*":true,
"arch/arm/boot/dts/imx7*":true,
"arch/arm/boot/dts/imx2*":true,
"arch/arm/boot/dts/imx3*":true,
"arch/arm/boot/dts/imx5*":true,
"arch/arm/boot/dts/imx6d*":true,
"arch/arm/boot/dts/imx6q*":true,
"arch/arm/boot/dts/imx6s*":true,
"arch/arm/boot/dts/imx6ul-*":false,
"arch/arm/boot/dts/imx6ull-9x9*":true,
"arch/arm/boot/dts/imx6ull-14x14-ddr*":true,
/*屏蔽不相关开发板*/
"board/[a-e]*":true,
"board/[g-z]*":true,
"board/[A-Z]*":true,
"board/freescale/[a-l]*":true,
"board/freescale/[n-z]*":true,
"board/freescale/m5*":true,
"board/freescale/mx6s*":true,
"board/freescale/mx7*":true,
"board/freescale/mx[1-5]*":true,
/*屏蔽不用的芯片配置文件*/
"configs/[a-l]*":true,
"configs/[n-z]*":true,
"configs/[A-Z]*":true,
"configs/m[a-w]*":true,
"configs/mx[^6]*":true,
"configs/mx6[^u]*":true,
"configs/mx6ulz*":true,
"configs/mx6ul_*":true,
/*屏蔽不用的芯片头文件*/
"include/configs/[0-9]*":true,
"include/configs/[^m]*.h":true,
"include/configs/m[^x]*.h":true,
"include/configs/mx[^6]*.h":true,
"include/configs/mx6[^u]*.h":true,
/*屏蔽不用的设备树文件*/
"arch/arm/dts/[0-9]*":true,
"arch/arm/dts/[^i]*":true,
"arch/arm/dts/im[^x]*":true,
"arch/arm/dts/imx[^6]*":true,
"arch/arm/dts/imx6[^u]*":true,
"arch/arm/dts/imx6ull-[^h]*":false,
"arch/arm/dts/imx6ul-[a-t]*":true,
},
"files.associations": {
"panel.h": "c",
"video.h": "c",
"mxsfb.h": "c",
"fb.h": "c",
"device-internal.h": "c"
}
}
4. 创建自己的开发板文件
其实就是拷贝一份mx6ullevk的开发板相关文件,并改成自己的开发板名字修改。我在做这部分内容时,将其分为两部分进行,分别是非设备树文件的移植和设备树文件的移植 。
a 非设备树文件的移植
这一步和正点原子教程没什么区别,但是相关目录有变动。
- defconfig文件拷贝和修改
拷贝:
cp configs/mx6ull_14x14_evk_emmc_defconfig configs/mx6ull_hezztek_defconfig
修改:在mx6ull_hezztek_defconfig找到CONFIG_DEFAULT_DEVICE_TREE这一行,改为
CONFIG_DEFAULT_DEVICE_TREE="imx6ull-hezztek"
- 头文件拷贝和修改
拷贝
cp include/configs/mx6ullevk.h include/configs/mx6ull_hezztek.h
修改:这里默认的就是14x14_evk和alpha开发板上的芯片一致,ddr默认512Mb,默认EMMC所以标配的开发板没必要修改。其他版本如NAND版则要根据自己的开发板型号具体修改。
- board拷贝和修改
拷贝整个文件夹
cp board/freescale/mx6ullevk/ -r board/freescale/mx6ull_hezztek
修改:这里要改c文件,Makefile,MAINTAINERS,Kconfig,imximage.cfg共计五项内容。
这里可以看到,seeed公司的开发板已经在官方uboot中维护了直接可以用,但是我们需要自己改。
- c文件修改
首先要修改一下c文件的名字
mv mx6ullevk.c mx6ull_hezztek.c
打开c文件,搜索一切和14x14相关的字符。发现了checkboard函数,我们往里面修改成自己的开发板。
int checkboard(void)
{
if (is_mx6ull_9x9_evk())
puts("Board: MX6ULL 9x9 EVK\n");
else if (is_cpu_type(MXC_CPU_MX6ULZ))
puts("Board: MX6ULZ 14x14 EVK\n");
else
puts("Board: MX6ULL HEZZTEK\n");
return 0;
}
- Makefile修改
Makefile的输出目标修改成对应的c文件的名字。
obj-y := mx6ull_hezztek.o
- MAINTAINERS修改
将mx6ull_14x14_evk替换为自己的开发板,其他的不用管:
M: Peng Fan <peng.fan@nxp.com>
S: Maintained
F: board/freescale/mx6ull_hezztek/
F: include/configs/mx6ull_hezztek.h
F: configs/mx6ull_hezztek_defconfig
F: configs/mx6ull_14x14_evk_plugin_defconfig
F: configs/mx6ulz_14x14_evk_defconfig
- Kconfig修改
修改mx6ullevk对应的文件和目录
if TARGET_MX6ULL_HEZZTEK
config SYS_BOARD
default "mx6ull_hezztek"
config SYS_VENDOR
default "freescale"
config SYS_CONFIG_NAME
default "mx6ull_hezztek"
config IMX_CONFIG
default "board/freescale/mx6ull_hezztek/imximage.cfg"
config SYS_TEXT_BASE
default 0x87800000
endif
- imximage.cfg修改
修改plugin文件的目录:
#ifdef CONFIG_USE_IMXIMG_PLUGIN
/*PLUGIN plugin-binary-file IRAM_FREE_START_ADDR*/
PLUGIN board/freescale/mx6ull_hezztek/plugin.bin 0x00907000
imximage.cfg中ddr校准数据修改
还要修改下面的DDR校准信息,需要提前使用nxp的ddr测试工具得到ddr校准数据后,向对应的地址进行修改。这一步很重要,不会报错,但是不改的话大概率u-boot没法正常启动。
校准信息每块开发板都不一样,举个例子,我从ddr测试工具中得到了这些数据,那么imximage.cfg中对应的地址就要用这些数据去修改:
//=============================================================================
// DDR Controller Registers
//=============================================================================
// Manufacturer: Micron
// Device Part Number: MT41K256M16HA-125
// Clock Freq.: 400MHz
// Density per CS in Gb: 4
// Chip Selects used: 1
// Number of Banks: 8
// Row address: 15
// Column address: 10
// Data bus width 16
//=============================================================================
setmem /32 0x021b001c = 0x00008000 // MMDC0_MDSCR, set the Configuration request bit during MMDC set up
//=============================================================================
// Calibration setup.
//=============================================================================
setmem /32 0x021b0800 = 0xA1390003 // DDR_PHY_P0_MPZQHWCTRL, enable both one-time & periodic HW ZQ calibration.
// For target board, may need to run write leveling calibration to fine tune these settings.
setmem /32 0x021b080c = 0x00000000
//Read DQS Gating calibration
setmem /32 0x021b083c = 0x013C0140 // MPDGCTRL0 PHY0
//Read calibration
setmem /32 0x021b0848 = 0x40402C32 // MPRDDLCTL PHY0
//Write calibration
setmem /32 0x021b0850 = 0x4040362C // MPWRDLCTL PHY0
//read data bit delay: (3 is the reccommended default value, although out of reset value is 0)
setmem /32 0x021b081c = 0x33333333 // MMDC_MPRDDQBY0DL
setmem /32 0x021b0820 = 0x33333333 // MMDC_MPRDDQBY1DL
//write data bit delay:
setmem /32 0x021b082c = 0xF3333333 // MMDC_MPWRDQBY0DL
setmem /32 0x021b0830 = 0xF3333333 // MMDC_MPWRDQBY1DL
//DQS&CLK Duty Cycle
setmem /32 0x021b08c0 = 0x00921012 // [MMDC_MPDCCR] MMDC Duty Cycle Control Register
// Complete calibration by forced measurement:
setmem /32 0x021b08b8 = 0x00000800 // DDR_PHY_P0_MPMUR0, frc_msr
//=============================================================================
// Calibration setup end
//=============================================================================
- 图形界面配置文件修改
在arch/arm/mach-imx/mx6/Kconfig中找到下列内容:
config TARGET_MX6ULL_14X14_EVK
bool "Support mx6ull_14x14_evk"
depends on MX6ULL
select BOARD_LATE_INIT
select DM
select DM_THERMAL
select IMX_MODULE_FUSE
select OF_SYSTEM_SETUP
imply CMD_DM
复制这些内容到下方,然后改成自己的开发板
config TARGET_MX6ULL_HEZZTEK
bool "Support mx6ull_hezztek"
depends on MX6ULL
select BOARD_LATE_INIT
select DM
select DM_THERMAL
select IMX_MODULE_FUSE
select OF_SYSTEM_SETUP
imply CMD_DM
文件的最后还有source加载行,在mx6ullevk旁边增加自己的开发板。
source "board/freescale/mx6ul_14x14_ddr3_val/Kconfig"
source "board/freescale/mx6ul_14x14_lpddr2_val/Kconfig"
source "board/freescale/mx6ull_hezztek/Kconfig"
source "board/freescale/mx6ullevk/Kconfig"
source "board/freescale/mx6ull_ddr3_val/Kconfig"
source "board/grinn/liteboard/Kconfig"
b 设备树文件的移植
这一步是旧版本所没有的,我参考了正点原子linux的设备树移植。
1. 观察imx6ullevk开发板的设备树结构。
打开arch/arm/dts/imx6ull-14x14-evk.dts进行观察,发现这里的内容很简短,说明大部分节点信息放在了头文件里。
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
//
// Copyright (C) 2016 Freescale Semiconductor, Inc.
/dts-v1/;
#include "imx6ull.dtsi"
#include "imx6ul-14x14-evk.dtsi"
#include "imx6ul-14x14-evk-u-boot.dtsi"
/ {
model = "i.MX6 ULL 14x14 EVK Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
};
&clks {
assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>;
assigned-clock-rates = <320000000>;
};
首先是imx6ull.dtsi,这里面放了代表imx6ull共性的节点,如cpu,usdhc存储接口等,因此这个文件不用改。
然后是imx6ul-14x14-evk.dtsi,这里面放了代表evk开发板特性的节点信息,因此需要拷贝。
最后是imx6ul-14x14-evk-u-boot.dtsi,这里放了代表dm总线相关的配置信息,是u-boot特性节点。因为正点原子alpha板需要的总线和evk需要的基本一样,所以也不用改。(原则上也需要拷贝一下)
2. 设备树文件的拷贝
综上,对于imx6ull alpha开发板,必须复制并修改的文件有imx6ull-14x14-evk.dts和imx6ul-14x14-evk.dtsi改名为imx6ull-hezztek.dts和imx6ull-hezztek.dtsi,imx6ull-hezztek.dts中修改头文件名字
#include "imx6ull.dtsi"
#include "imx6ull-hezztek.dtsi"
#include "imx6ul-14x14-evk-u-boot.dtsi"
ps:这个目录下能看到seeed公司的imx6ull开发板,所以要是想跳过移植这步,也可以直接用seeed的开发板。但也可以从我的源码仓库里下载。
最后因为我是512M的emmc版本,所以要从arch/arm/dts/imx6ull-14x14-evk-emmc.dts中复制emmc的存储节点信息:
&usdhc2 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2_8bit>;
pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
bus-width = <8>;
non-removable;
status = "okay";
};
这个节点复制到arch/arm/dts/imx6ull-hezztek.dts
然后编译,运行成功,就可以开始移植LCD和网络驱动接口了。
5. LCD移植
我用了7英寸1024x600的屏幕,虽然接口和原版基本相同,但是数值不同,所以需要修改。
1. 观察原版LCD驱动文件结构
搜索“lcdif”关键字:
在imx6ul-14x14-evk.dtsi文件中能看到lcdif节点,这里保存了lcd屏的参数信息。
在imx6ull.dtsi包含的头文件imx6ul.dtsi文件中能看到lcd屏的配置信息。
lcdif: lcdif@21c8000 {
compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
reg = <0x021c8000 0x4000>;
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
<&clks IMX6UL_CLK_LCDIF_APB>,
<&clks IMX6UL_CLK_DUMMY>;
clock-names = "pix", "axi", "disp_axi";
status = "disabled";
};
这里能看到匹配字符串,回到uboot根目录,在drivers/video范围内进行搜索,关键词:.compatible = “fsl ,得到以下结果:
可以看到老芯片的驱动都放在了drivers/video/mxsfb.c里了。
2. 修改LCD驱动。
修改方法和linux下的LCD设备树修改差不多。也要结合uboot掌节的内容。
- 首先,因为正点原子的开发板没有lcd开关,所以要在board/freescale/mx6ull_hezztek/mx6ull_hezztek.c中屏蔽lcd的开关的代码,位了展示出来,我用增加#if 0 #endif的方式注释了这段代码,可以直接删除。
static int setup_lcd(void)
{
enable_lcdif_clock(LCDIF1_BASE_ADDR, 1);
imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
/* Reset the LCD */
#if 0
gpio_request(IMX_GPIO_NR(5, 9), "lcd reset");
gpio_direction_output(IMX_GPIO_NR(5, 9) , 0);
udelay(500);
gpio_direction_output(IMX_GPIO_NR(5, 9) , 1);
#endif
/* Set Brightness to high */
gpio_request(IMX_GPIO_NR(1, 8), "backlight");
gpio_direction_output(IMX_GPIO_NR(1, 8) , 1);
return 0;
}
然后在arch/arm/dts/imx6ull-hezztek.dtsi中修改lcdif节点的配置信息,下面是7寸屏的时序信息:
&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>;
};
};
};
};
要注意的一点是bits-per-pixel的值要设为24,这是因为在mxsfb.c搜索bpp关键词可以看出,bpp没有支持32bit的选项,实际上这里的规则和之前的linux设备树是不同的,因此设备树那里的色深bits-per-pixel要写24而不是32(老版本linux内核中18bit和24bit均写32)。
下面展示一下drivers/video/mxsfb.c中和色深相关的代码,用关键词bpp搜素。
sprintf(panel.modeIdent, "%dx%dx%d", mode.xres, mode.yres, bpp);
panel.winSizeX = mode.xres;
panel.winSizeY = mode.yres;
panel.plnSizeX = mode.xres;
panel.plnSizeY = mode.yres;
switch (bpp) {
case 24:
case 18:
panel.gdfBytesPP = 4;
panel.gdfIndex = GDF_32BIT_X888RGB;
break;
case 16:
panel.gdfBytesPP = 2;
panel.gdfIndex = GDF_16BIT_565RGB;
break;
case 8:
panel.gdfBytesPP = 1;
panel.gdfIndex = GDF__8BIT_INDEX;
break;
default:
printf("MXSFB: Invalid BPP specified! (bpp = %i)\n", bpp);
return NULL;
}
panel.memSize = mode.xres * mode.yres * panel.gdfBytesPP;
最后在lcdif_dat修改引脚的电气属性,将lcdif_dat节点里所有0x79改成0x49这样是为了降低IO驱动能力,防止alpha板上的模拟开关影响网络芯片(引自正点原子教材)
pinctrl_lcdif_dat: lcdifdatgrp {
fsl,pins = <
MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x49
MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x49
MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x49
MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x49
MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x49
MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x49
MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x49
MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x49
MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x49
MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x49
MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x49
MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x49
MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x49
MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x49
MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x49
MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x49
MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x49
MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x49
MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x49
MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x49
MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x49
MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x49
MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x49
MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x49
>;
};
至此,uboot阶段的屏幕可以正常点亮了。可以看到屏幕显示了uboot的版本信息。
6. 网络驱动移植
正点原子alpha v2.4开发板用了SR8201F驱动,这个驱动在复位结束后需要150ms的延时等待后才能操作。还有一点是开发板将GPIO5_IO07和GPIO5_IO08分别用作enet1和enet2的复位引脚。这是这部分要修改的两个内容。
1. 观察原版网络驱动文件结构。
通过上次编译成功的输出信息,列出包含关键词“drivers/net”的行,获取了以下内容:
CC drivers/net/phy/phy.o
CC drivers/net/eth-phy-uclass.o
CC drivers/net/phy/micrel_ksz8xxx.o
CC drivers/net/fec_mxc.o
网络驱动的相关修改必然在这些文件里,其中eth-phy-uclass.c用于获取设备信息,重点要看phy.c和fec_mxc.c。
从fec_mxc.c中可以看出,实际上我们并不需要手动添加延时,因为复位延时的设备树节点加载和使用已经定义在了原版驱动中,所以我们不用对驱动做任何修改,只要改设备树节点就行了。
NXP原版设备树节点加载代码:
NXP原版驱动复位代码:这里能看到复位按键gpio节点加载(phy-reset-gpios)、复位低电平持续时间加载(phy-reset-duration),和延时时间加载(phy-reset-post-delay)
如果使用的是LAN8720A网络芯片的开发板版本,可能还要在驱动中另做修改。
2. 修改网络驱动。
a 开发板将GPIO5_IO07和GPIO5_IO08分别用作enet1和enet2的复位引脚,但是原版将这两个引脚用于SPI4.所以一旦定义了自己的复位开关,就要将spi4中和这两个引脚相关代码全部屏蔽,才能编译通过。然后在下方增加复位开关定义的节点。
在io复用节点做以下修改:
还要在spi4中取消这两个引脚的加载和使用
最后要在fec1和fec2字节点下增加SR8201的开关复位信息。
至此网络设备的配置就完成了。烧录进sd卡然后启动。启动uboot时,系统会提示ethernet地址没有设置,这是网口的地址。这个error是不影响使用的,u-boot仍然能正常运行,只要设置好参数eth1addr就可以正常运行了。
设置参数如下
setenv ipaddr 192.168.31.4
setenv eth1addr bb:af:e3:05:2c:f0(十六进制数字随便填)
setenv gatewayip 192.168.31.1
setenv netmask 255.255.255.0
setenv serverip 192.168.31.3
saveenv
这一步之后,ping一下服务器
网络移植成功!
但值得注意的一点是,此时默认的网口是enet2,并不是教程中用的enet1。
另外,图形化配置界面里可以配置host命令用于dns解析。