开发板类型:emmc、7寸屏
1 NXP官方开发板uboot编译测试
1.1 获取源码
1)源码路径:1、例程源码->4、NXP 官方原版 Uboot 和 Linux -> uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2。
 2)将源码拷贝到ubuntu中的~/linux/IMX6ULL/uboot/temp目录下,解压。解压后入下图所示:
 
1.2 编译
1 配置
 在编译之前首先要配置uboot,uboot的配置文件在configs目录下,因为开发是使用的是14x14mm尺寸的芯片,emmc版本,所以关注官方的 mx6ull_14x14_evk_emmc_defconfig配置文件。
 2 编译
 编写脚本/mx6ull_14x14_evk_emmc.sh,内如如下
#!/bin/bashmake ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distcleanmake ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfigmake V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
给脚本可执行权限,执行脚本
./mx6ull_14x14_evk_emmc.sh
3 烧写验证
 1)烧写
 将逻辑开发时用到的下载软件imxdownload拷贝到该目录下,使用下面语句下载到SD卡中。
chmos 777 imxdownload
./imxdownload u-boot.bin /dev/sdb
sdb是SD卡,下载后将SD卡插入开发版的板槽,打开MobaXterm软件,设置好串口并打开,复位开发板后可以看到如下信息:
 
 2)SD卡和emmc驱动检查
 使用如下命令验证SD卡和emmc,
mmc list     	//查看设备中的mmc设备
mmc dev 0/1		//切换mmc设备
mmc info		//查看mmc设备信息
查看结果如下,SD卡和emmc都可以查到。
 
 3)LCD检查
 因为开发板上链接的是7寸屏,所以不会显示NXP的logo
 4)网络检查
 uboot启动的时候提示“Board Net Initialization Failed”和“No ethernet found.”这两行,说明网络驱动也是有问题的。这是因为开发版的网络芯片复位引脚和NXP官方开发版不一样,因此需要修改驱动。
4 总结
 移植NXP官方I.MX6ULL EVK开发板的uboot到正点原子EMMC开发板上的运行情况:
- uboot启动正常,DRAM识别正确,SD卡和EMMC驱动正常
- uboot里面的LCD默认是4.3寸480写72分辨率的,其他分辨率需修改
- 网络不能正常工作,识别不出网络信息,需要修改
移植需要做的工作:
 4. 在uboot中添加自己的开发板
 5. 解决LCD和网络驱动问题
2 在U-boot中添加自己的开发板
2.1 添加开发板默认配置文件
1)所在目录:configures
 2)复制文件:mx6ull_14x14_evk_emmc_defconfig
 3)重命名为:mx6ull_alientek_emmc_defconfig
 命令如下:
cd configs
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_alientek_emmc_defconfig
4)修改内容:
 然后将文件mx6ull_alientek_emmc_defconfig中的内容改成下面内容:
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y
CONFIG_CMD_GPIO=y
可以看出只修改了第1行和第4行
2.2 添加开发板对应的头文件
1)目录:include/configs
 2)复制文件:mx6ullevk.h
 3)重命令为:mx6ull_alientek_emmc.h
 命令如下:
cp include/configs/mx6ullevk.h include/configs/mx6ull_alientek_emmc.h
4)修改内容:
 将
#ifndef __MX6ULLEVK_CONFIG_H
#define __MX6ULLEVK_CONFIG_H
修改为:
#ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H
#define __MX6ULL_ALIENTEK_EMMC_CONFIG_H
这里面有很多宏定义,这些宏基本是用来配置uboot的,也有些是I.MX6ULL的配置项,如果项使能或者禁止uboot的某些功能,则修改本文件。里面内容较多在后面详细记录。
2.3 添加开发板对应的板级文件
uboot的每个板子都有一个对应的文件夹用来存放板级文件,I.MX系列芯片的板级文件在board/freescale目录下。
 1)目录:board/freescal
 2)复制文件:mx6ullevk
 3)重命名为:mx6ull_alientek_emmc
 命令如下:
cd board/freescal
cp -r mx6ullevk mx6ull_alientek_emmc
4)进入mx6ull_alientek_emmc目录,将mx6ullevk.c重命名为mx6ull_alientek_emmc.c,命令如下:
cd mx6ull_alientek_emmc
mv mx6ullevk.c mx6ull_alientek_emmc
5)修改mx6ull_alientek_emmc内容:
-  修改 Makefile文件
 修改内容如下:
  重点是红框内容,这样才会编译mx6ull_alientek_emmc.c 
-  修改 imximage.cfg文件
 将PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000改为: PLUGIN board/freescale/mx6ull_alientek_emmc /plugin.bin 0x00907000
-  修改 Kconfig文件if TARGET_MX6ULL_ALIENTEK_EMMCconfig SYS_BOARDdefault "mx6ull_alientek_emmc"config SYS_VENDORdefault "freescale"config SYS_SOCdefault "mx6"config SYS_CONFIG_NAMEdefault "mx6ull_alientek_emmc"endif
-  修改 MAINTAINERS文件MX6ULLEVK BOARD M: Peng Fan <peng.fan@nxp.com> S: Maintained F: board/freescale/mx6ull_alientek_emmc/ F: include/configs/mx6ull_alientek_emmc.h F: configs/mx6ull_alientek_emmc_defconfig
2.4 修改U-boot图形界面配置文件
1)修改文件:arch/arm/cpu/armv7/mx6/Kconfig
 2)修改内容:
 在207行加入如下内容:
201 config TARGET_MX6ULL_9X9_EVK
202     bool "Support mx6ull_9x9_evk"
203     select MX6ULL
204     select DM
205     select DM_THERMAL
206 
207 config TARGET_MX6ULL_ALIENTEK_EMMC
208     bool "Support mx6ull_alientek_emmc"
209     select MX6ULL
210     select DM
211     select DM_THERMAL
212 
213 config TARGET_SECOMX6
214     bool "secomx6 boards"
在最后一行的endif前添加如下内容:
 source "board/freescale/mx6ull_alientek_emmc/Kconfig"
2.5 使用新添加的板子编译uboot
1)在uboot跟目录新建一个名为mx6ull_alientek_emmc.sh的脚本,内容如下:
#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
2)执行脚本,脚本要有可执行权限
./imx6ull_alientek_emmc.sh
3)查看是否添加成功
grep -nr "mx6ull_alientek_emmc.h"
如果有很多文件都引用了mx6ull_alientek_emmc.h这个头文件,则说明板子添加成功,如图所示:
 
 4)下载验证:
 下载到SD卡中,开启开发板,在串口中可以看到如下信息:
 
 此时屏幕上是无法显示NXP的logo的,因为屏幕驱动不正确,同时网络驱动也是有问题的。
2.6 LCD驱动修改
一般uboot的驱动修改都是在xxx.h和xxx.c这两个文件中进行的。比如 mx6ull_alientek_emmc.h 和mx6ull_alientek_emmc.c 这两个文件。
1)一般修改LCD驱动重点注意一下几点:
 ①、LCD所使用的GPIO,查看uboot中LCD的IO配置是否正确
 ②、LCD背光引脚GPIO配置
 ③、LCD配置参数是否正确
2)正点原子的LCD原理图和NXP的相同,也就是LCD的IO和背光IO都一样,因此IO部分就不需要修改了。只修改LCD的参数即可
3)参数修改:
 修改mx6ull_alientek_emmc.c文件
 ① 目录:board/freescale/mx6ull_alientek_emmc/mx6ull_alientek_emmc.c
② 修改内容:
 找到display_info_t结构体,大约在780行,修改为如下内容
struct display_info_t const displays[] = {{.bus = MX6UL_LCDIF1_BASE_ADDR,.addr = 0,.pixfmt = 24,.detect = NULL,.enable = do_enable_parallel_lcd,.mode   = {.name           = "TFT7016",	//LCD 名字,要和环境变量中的 panel 相等.xres           = 1024,			//LCD X 轴和 Y 轴像素数量.yres           = 600,.pixclock       = 19531,		//像素时钟,每个像素时钟周期的长度,单位为皮秒.left_margin    = 140,			//HBP,水平同步后肩。.right_margin   = 160,			//HFP,水平同步前肩.upper_margin   = 20,			//VBP,垂直同步后肩。.lower_margin   = 12,			//VFP,垂直同步前肩。.hsync_len      = 20,			//HSPW,行同步脉宽。.vsync_len      = 3,			//VSPW,垂直同步脉宽。.sync           = 0,.vmode          = FB_VMODE_NONINTERLACED		//大多数使用 FB_VMODE_NONINTERLACED,也就是不使用隔行扫描
} } };pixclock的计算方法:
 7寸1024*600分辨率的屏幕像素时钟为51.2MHz
pixclock=(1/51200000)*10^12 = 19531
4)验证
 重新编译代码,将编译出的u-boot.bin下载到SD卡中。重启开发板,此时屏幕上会显示NXP的logo。
 若没有logo则查看环境变量panel是否为TFT7016,如果不是则用如下命令修改环境变量。
setenv panel TFT7016
saveenv
2.7 网络修改
开发板为2.4以前版本。使用的PHY芯片为LAN8720。正点原子 开发板 ENET1 引脚与NXP官方 I.MX6ULL EVK开发板只有复位引脚不同,I.MX6U-ALPHA 开发板 ENET1 上连接的 LAN8720A器件地址为 0X0,所以ENET1网络驱动的重点只有如下三点:
 ① ENET1复位引脚初始化
 ② LAN8720A的器件ID
 ③ LAN8720驱动
关于 ENET2 网络驱动的修改也注意一下三点:
 ① ENET2 的复位引脚,ENET2 的复位引脚 ENET2_RST 接到了I.MX6ULL 的 SNVS_TAMPER8 上。
 ② ENET2 所使用的 PHY 芯片器件地址,PHY 器件地址为 0X1。
 ③ LAN8720 驱动,ENET1 和 ENET2 都使用的 LAN8720,所以驱动肯定是一样的。
2.7.1 网络PHY芯片修改
打开mx6ull_alientek_emmc.h,所在目录:include/configs,修改内容如下:
325 #ifdef CONFIG_CMD_NET
326 #define CONFIG_CMD_PING
327 #define CONFIG_CMD_DHCP
328 #define CONFIG_CMD_MII
329 #define CONFIG_FEC_MXC
330 #define CONFIG_MII
331 #define CONFIG_FEC_ENET_DEV     1
332 
333 #if (CONFIG_FEC_ENET_DEV == 0)
334 #define IMX_FEC_BASE            ENET_BASE_ADDR
335 #define CONFIG_FEC_MXC_PHYADDR          0x0		//改为0
336 #define CONFIG_FEC_XCV_TYPE             RMII
337 #elif (CONFIG_FEC_ENET_DEV == 1)
338 #define IMX_FEC_BASE            ENET2_BASE_ADDR
339 #define CONFIG_FEC_MXC_PHYADDR      0x1
340 #define CONFIG_FEC_XCV_TYPE     RMII
341 #endif
342 #define CONFIG_ETHPRIME         "FEC"
343 
344 #define CONFIG_PHYLIB
345 #define CONFIG_PHY_SMSC		//这个地方修改为CONFIG_PHY_SMSC
346 #endif
2.7.2 删除uboot中的74LV595驱动代码
打开imx6ull_alientek_emmc.c,
-  删除与74LV595有关代码 
 1)将:#define IOX_SDI IMX_GPIO_NR(5, 10) #define IOX_STCP IMX_GPIO_NR(5, 7) #define IOX_SHCP IMX_GPIO_NR(5, 11) #define IOX_OE IMX_GPIO_NR(5, 8)替换为: #define ENET1_RESET IMX_GPIO_NR(5, 7) #define ENET2_RESET IMX_GPIO_NR(5, 8)因为正点原子没有使用74LV595,所以需要将与74LV595有关代码删掉,IOX开头的宏定义就是与74LV595有关的。 
 ENET1 的复位引脚连接到 SNVS_TAMPER7 上,对应 GPIO5_IO07,ENET2 的复位引脚连接到 SNVS_TAMPER8 上,对应 GPIO5_IO082)删除 iox_pads[]数组、iox74lv_init()函数和iox74lv_set函数。
 3)删除board_init()函数中的imx_iomux_v3_setup_multiple_pads和iox74lv_init两行,这两行是用来初始化74lv595函数的
2.7.3 添加I.MX6ULL-ALPHA开发板网络复位引脚驱动
1)fec1_pads和fec2_pads是ENET1和ENET2两个网口的IO配置参数,在这两个数组中添加两个网口的复位IO配置参数,完成以后如下图:
/** pin conflicts for fec1 and fec2, GPIO1_IO06 and GPIO1_IO07 can only* be used for ENET1 or ENET2, cannot be used for both.*/
static iomux_v3_cfg_t const fec1_pads[] = {MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),	//新添加
};static iomux_v3_cfg_t const fec2_pads[] = {MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_DATA0__ENET2_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_DATA1__ENET2_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),MX6_PAD_ENET2_TX_EN__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_DATA0__ENET2_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_DATA1__ENET2_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),	//新添加
};
2)修改setup_iomux_fec函数,该函数根据fec1_pads和fec2_pads两个配置数组来初始化I.MX6ULL的网络IO。需要再该函数中添加网络复位IO的初始化代码,并且复位一下PHY芯片。修改后如下:
static void setup_iomux_fec(int fec_id)
{if (fec_id == 0){imx_iomux_v3_setup_multiple_pads(fec1_pads,ARRAY_SIZE(fec1_pads));//ENET1复位gpio_direction_output(ENET1_RESET, 1);gpio_set_value(ENET1_RESET, 0);mdelay(20);gpio_set_value(ENET1_RESET, 1);}else{imx_iomux_v3_setup_multiple_pads(fec2_pads,ARRAY_SIZE(fec2_pads));//ENET2复位gpio_direction_output(ENET2_RESET, 1);gpio_set_value(ENET2_RESET, 0);mdelay(20);gpio_set_value(ENET2_RESET, 1);}
}
2.7.4 修改drivers/net/phy/phy.c文件的函数
uboot的LAN8720的驱动有些问题,需要修改,打开文件
 drivers/net/phy/phy.c,找到函数 genphy_update_link,这是个通用 PHY 驱动函数,此函数用于更新 PHY 的连接状态和速度。使用 LAN8720A 的时候需要在此函数中添加一些代码,修改后的函数 genphy_update_link 如下所示:
int genphy_update_link(struct phy_device *phydev)
{unsigned int mii_reg;
//新添加代码为ifdef部分
#ifdef CONFIG_PHY_SMSCstatic int lan8720_flag = 0;int bmcr_reg = 0;if (lan8720_flag == 0) {bmcr_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR) & 0X8000) {udelay(100);}phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg);lan8720_flag = 1;}
#endif/** Wait if the link is up, and autonegotiation is in progress* (ie - we're capable and it's not done)*/mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
······
return 0;
2.7.5 下载验证
1)编译代码,下载到SD卡中,可以从串口助手上看到 Net:FEC1 字样,说明网络驱动配置成功。如下图所示:
 
 2)修改环境变量,配置开发板网络:
 1)配置网络:
setenv ipaddr 192.168.0.100  //开发板 IP 地址
setenv ethaddr b8:ae:1d:01:00:00 //开发板网卡 MAC 地址
setenv gatewayip 192.168.0.1 //开发板默认网关
setenv netmask 255.255.255.0  //开发板子网掩码
setenv serverip 192.168.0.12  //服务器地址,也就是 Ubuntu 地址
saveenv //保存环境变量
2)测试网络:
ping 192.168.0.12
结果如图:
 
 我的这个开始链接出现问题是因为网线插错网口了,应该插到挨着db9的网口上。
终于搞完了,详细的解释后面补充