正点原子I.MX6U-MINIu-boot过程移植详解

Posted 果果小师弟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正点原子I.MX6U-MINIu-boot过程移植详解相关的知识,希望对你有一定的参考价值。

正点原子的I.MX6ULL开发板参考的是NXP官方的I.MX6ULL EVK开发板做的硬件

Linux的移植要复杂的多,在移植Linux之前我们需要先移植一个 bootloader 代码,这个 bootloader 代码用于启动Linux 内核,bootloader有很多,常用的就是 U-Boot。移植好U-Boot以后再移植Linux 内核,移植完Linux内核以后Linux还不能正常启动,还需要再移植一个根文件系统(rootfs),根文件系统里面包含了一些最常用的命令和文件。所以 U-Boot、Linux kernel 和 rootfs 这三者一起构成了一个完整的Linux 系统,一个可以正常使用、功能完善的 Linux 系统

uboot 的全称是Universal Boot Loader,uboot是一个遵循GPL协议的开源软件,uboot是一
个裸机代码,可以看作是一个裸机综合例程。现在的uboot已经支持液晶屏、网络、USB 等高
级功能。

Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段bootloader程序。这段bootloader程序会先初始化DDR等外设,然后将Linux内核从flash(NAND,NOR FLASH,SD,MMC 等)拷贝到 DDR 中,最后启动 Linux 内核。当然了,bootloader 的实际工作要复杂的多,但是它最主要的工作就是启动Linux 内核,bootloader和Linux内核的关系就跟PC上的 Bios 和Windows的关系一样,bootloader就相当于BIOS。所以我们要先搞定bootloader,很庆幸,有很多现成的bootloader 软件可以使用,比如U-Boot、vivi、RedBoot等。

一、U-Boot命令

=> help
?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
bmode   - sd1|sd2|qspi1|normal|usb|sata|ecspi1:0|ecspi1:1|ecspi1:2|ecspi1:3|esdhc1|esdhc2|esdhc3|esdhc4 [noreset]
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm   - boot application image from memory
bootp   - boot image via network using BOOTP/TFTP protocol
bootvx  - Boot vxWorks from an ELF image
bootz   - boot Linux zImage image from memory
clocks  - display clocks
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
dcache  - enable or disable data cache
dhcp    - boot image via network using DHCP/TFTP protocol
dm      - Driver model low level access
echo    - echo args to console
editenv - edit environment variable
env     - environment handling commands
erase   - erase FLASH memory
exit    - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls  - list files in a directory (default /)
ext4load- load binary file from a Ext4 filesystem
ext4ls  - list files in a directory (default /)
ext4size- determine a file's size
ext4write- create a file in the root directory
false   - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
fatsize - determine a file's size
fatwrite- write file into a dos filesystem
fdt     - flattened device tree utility commands
flinfo  - print FLASH memory information
fstype  - Look up a filesystem type
fuse    - Fuse sub-system
go      - start application at address 'addr'
gpio    - query and control gpio pins
help    - print command description/usage
i2c     - I2C sub-system
icache  - enable or disable instruction cache
iminfo  - print header information for application image
imxtract- extract a part of a multi-image
itest   - return true/false on integer compare
load    - load binary file from a filesystem
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loadx   - load binary file over serial line (xmodem mode)
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
ls      - list files in a directory (default /)
md      - memory display
mdio    - MDIO utility commands
mii     - MII utility commands
mm      - memory modify (auto-incrementing address)
mmc     - MMC sub system
mmcinfo - display MMC info
mtest   - simple RAM read/write test
mw      - memory write (fill)
nfs     - boot image via network using NFS protocol
nm      - memory modify (constant address)
ping    - send ICMP ECHO_REQUEST to network host
pmic    - PMIC
printenv- print environment variables
protect - enable or disable FLASH write protection
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
save    - save file to a filesystem
saveenv - save environment variables to persistent storage
setenv  - set environment variables
setexpr - set environment variable as the result of eval expression
sf      - SPI flash sub-system
showvar - print local hushshell variables
size    - determine a file's size
sleep   - delay execution for some time
source  - run script from memory
test    - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true    - do nothing, successfully
usb     - USB sub-system
usbboot - boot from USB device
version - print monitor, compiler and linker version

二、U-Boot移植

uboot 的移植并不是说我们完完全全的从零开始将uboot 移植到我们现在所使用的开发板或者开发平台上。这个对于我们来说基本是不可能的,这个工作一般是半导体厂商做的,半导体厂商负责将 uboot 移植到他们的芯片上,因此半导体厂商都会自己做一个开发板,这个开发板就叫做原厂开发板,比如大家学习STM32的时候听说过的discover开发板就是ST自己做的。

半导体厂商会将uboot 移植到他们自己的原厂开发板上,测试好以后就会将这个uboot发布出去,这就是大家常说的原厂BSP包。我们一般做产品的时候就会参考原厂的开发板做硬件,然后在原厂提供的BSP包上做修改,将uboot或者linux kernel移植到我们的硬件上。这个就是uboot 移植的一般流程:

  • ①、在uboot中找到参考的开发平台,一般是原厂的开发板。
  • ②、参考原厂开发板移植uboot到我们所使用的开发板上。

1、移植NXP官方的uboot到开发板

正点原子的I.MX6ULL开发板参考的是NXP官方的I.MX6ULL EVK开发板做的硬件。因此在移植 uboot的时候就可以以NXP官方的I.MX6ULL EVK开发板为蓝本。将 NXP官方的uboot移植到正点原子的I.MX6ULL开发板上。

1、编译一下NXP官方I.MX6ULL EVK开发板对应的uboot。

  • mx6ull开头的是I.MX6ULL 开发板的
  • 9x9mm 和 14x14mm 表示芯片的尺寸,正点原子使用的是14x14mm的芯片
  • 正点原子的I.MX6ULL有EMMC 和NAND两个版本的,我买的版本是EMMC版本的(flash)

使用如下命令编译NXP官方I.MX6ULL EVK开发板的uboot:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16

编译完成以后会生成u-boot.bin、u-boot.imx 等文件。

2、烧写验证与驱动测试

imxdownload软件拷贝到uboot源码根目录下,然后使用imxdownload软件将u-boot.bin烧写到 SD 卡中,烧写命令如下:

chmod 777 imxdownload //给予 imxdownload 可执行权限
./imxdownload u-boot.bin /dev/sdg  //烧写 u-boot.bin 到 SD 卡中

烧写完成以后将SD卡插入 I.MX6U-ALPHA 开发板的TF卡槽中,最后设置开发板从SD卡启动。打开 SecureCRT,设置好开发板所使用的串口并打开,复位开发板,SecureCRT 接收到。

从图可以看出,uboot 启动正常,虽然我们用的是NXP官方I.MX6ULL开发板的uboot,但是在正点原子的I.MX6ULL开发板上是可以正常启动的,而且DRAM识别正确,为512MB。如果用的NAND版本的核心版的话uboot启动会失败!因为NAND核心版用的 256MB的DRAM。

3、SD 卡和 EMMC 驱动检查
检查一下SD卡和EMMC驱动是否正常,使用命令 mmc list 列出当前的 MMC 设备
从图可以看出,mmc 设备0 是SD 卡,SD卡容量为3.8GB,这个和我所使用的SD卡信息相符,说明 SD卡驱动正常。

再来检查MMC设备1,输入如下命令:

mmc dev 1
mmc info


从图可以看出,mmc设备1为EMMC,容量为3.6GB,说明 EMMC 驱动也成功,SD卡和EMMC的驱动都没问题。

4 、LCD 驱动检查

如果 uboot 中的 LCD 驱动正确的话,启动 uboot 以后 LCD 上应该会显示出NXP的 logo,如果你用的不是正点原子的 4.3 寸 480x272 分辨率的屏幕的话,那么 LCD 就不会显示NXP的logo 界面。因为 NXP 官方 I.MX6ULL 开发板的屏幕就是 4.3 寸 480x272 分辨率的,所以 uboot 默认 LCD 驱动是 4.3 寸 480x272 分辨率的。如果使用其他分辨率的 LCD 就需要修改 LCD 驱动。

5、网络驱动检查

boot 启动的时候提示Board Net Initialization FailedNo ethernet found这两行,说明网络驱动也有问题,正常情况下应该是如图所示提示


总结一下NXP官方I.MX6ULL EVK开发板的uboot在正点原子EMMC 版本I.MX6ULL开发板上的运行情况:

  • ① uboot 启动正常,DRAM 识别正确,SD 卡和EMMC驱动正常。
  • ② uboot 里面的LCD驱动默认是给 4.3 寸 480x272 分辨率的,如果使用的其他分辨率的屏幕需要修改驱动。
  • ③ 网络不能工作,识别不出来网络信息,需要修改驱动。

2、在 U-Boot中添加自己的开发板

1、添加开发板默认配置文件

先在configs目录下创建默认配置文件,复制mx6ull_14x14_evk_emmc_defconfig,然后重命名为 mx6ull_alientek_emmc_defconfig,命令如下:

cd configs
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_alientek_emmc_defconfig

然后将文件mx6ull_alientek_emmc_defconfig中的内容改成下面的:


2、添加开发板对应的头文件

在 目 录 include/configs 下 添 加 I.MX6ULL-ALPHA 开 发 板 对 应 的 头 文 件 , 复 制include/configs/mx6ullevk.h,并重命名为 mx6ull_alientek_emmc.h,命令如下:

cp include/configs/mx6ullevk.h mx6ull_alientek_emmc.h

拷贝完成以后将:

#ifndef __MX6ULLEVK_CONFIG_H
#define __MX6ULLEVK_CONFIG_H

改为:

#ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H
#define __MX6ULL_ALIENTEK_EMMC_CONFIG_H


mx6ull_alientek_emmc.h 里面有很多宏定义,这些宏定义基本用于配置uboot,也有一些I.MX6ULL 的配置项目。如果我们自己要想使能或者禁止uboot的某些功能,那就在mx6ull_alientek_emmc.h 里面做修改即可。mx6ull_alientek_emmc.h里面的内容比较多,去掉一些用不到的配置。

3、添加开发板对应的板级文件夹

uboot 中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上外设驱动文件等等。NXP 的 I.MX 系列芯片的所有板级文件夹都存放在board/freescale目录下,在这个目录下有个名为mx6ullevk 的文件夹,这个文件夹就是NXP官方I.MX6ULL EVK开发板的板级文件夹。复制mx6ullevk,将其重命名为mx6ull_alientek_emmc,命令如下:

cd board/freescale/
cp mx6ullevk/ -r mx6ull_alientek_emmc

进 入mx6ull_alientek_emmc目 录 中 , 将其中的mx6ullevk.c 文件重命名为mx6ull_alientek_emmc.c,命令如下:

cd mx6ull_alientek_emmc
mv mx6ullevk.c mx6ull_alientek_emmc.c


1 、修改mx6ull_alientek_emmc目录下的Makefile

将 mx6ull_alientek_emmc 下的 Makefile 文件内容改为如下所示

2 、修改mx6ull_alientek_emmc 目录下的 imximage.cfg 文件

将imximage.cfg中的下面一句:

PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000

改为:

PLUGIN board/freescale/mx6ull_alientek_emmc /plugin.bin 0x00907000


3 、修改mx6ull_alientek_emmc 目录下的 Kconfig 文件

修改 Kconfig 文件,修改后的内容如下:


4 、修改mx6ull_alientek_emmc 目录下的MAINTAINERS文件

修改 MAINTAINERS 文件,修改后的内容如下:

3、修改 U-Boot 图形界面配置文件

uboot 是支持图形界面配置,关于 uboot 的图形界面配置下一章会详细的讲解。修改文件arch/arm/cpu/armv7/mx6/Kconfig(如果用的 I.MX6UL 的话,应该修改arch/arm/Kconfig这个文件),在 207 行加入如下内容:


到此为止,I.MX6U开发板就已经添加到uboot中了,接下来就是编译这个新添加的开发板。

5、使用新添加的板子配置编译 uboot

使用如下命令来编译对应的 uboot:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12

编译完成以后uboot源码多了一些文件,其中u-boot.bin就是编译出来的uboot二进制文件。uboot是个裸机程序,因此需要在其前面加上头部(IVT、DCD等数据)才能在I.MX6U上执行,u-boot.imx文件就是添加头部以后的u-boot.bin,u-boot.imx 就是我们最终要烧写到开发板中的uboot 镜像文件。

编译完成以后就使用imxdownload将新编译出来的u-boot.bin烧写到 SD 卡中测试,注意这时候编译出来的uboot的LCD驱动和网络驱动是有问题的。

6、LCD 驱动修改

一般 uboot 中修改驱动基本都是在xxx.h和xxx.c这两个文件中进行的,xxx 为板子名称,比如 mx6ull_alientek_emmc.h 和 mx6ull_alientek_emmc.c 这两个文件。

一般修改 LCD 驱动重点注意以下几点:
①、LCD 所使用的 GPIO,查看uboot中LCD的IO配置是否正确。
②、LCD 背光引脚GPIO的配置。
③、LCD 配置参数是否正确。

正点原子的 I.MX6U-ALPHA 开发板 LCD 原理图和 NXP 官方 I.MX6ULL 开发板一致,也就是 LCD的IO和背光IO都一样的,所以IO部分就不用修改了。需要修改的之后LCD参数,打开文件 mx6ull_alientek_emmc.c,找到如下所示内容:

  • name :LCD 名字,要和环境变量中的 panel 相等。
  • xres 、yres :LCD X 轴和 Y 轴像素数量。
  • pixclock:像素时钟,每个像素时钟周期的长度,单位为皮秒。
  • left_margin :HBP,水平同步后肩。
  • right_margin :HFP,水平同步前肩。
  • upper_margin:VBP,垂直同步后肩。
  • lower_margin:VFP,垂直同步前肩。
  • hsync_len :HSPW,行同步脉宽。
  • vsync_len:VSPW,垂直同步脉宽。
  • vmode :大多数使用 FB_VMODE_NONINTERLACED,也就是不使用隔行扫描。

这里的参数要根据你的屏幕对应上面的参数要一一对应,不能错。

7、网络驱动修改

1 、I.MX6U-MINI开发板网络简介

I.MX6UL/ULL 内部有个以太网 MAC 外设,也就是 ENET,需要外接一个 PHY 芯片来实现网络通信功能,也就是内部 MAC+外部 PHY 芯片的方案

大家可能听过 DM9000 这个网络芯片,在一些没有内部MAC的CPU中,比如三星的2440,4412 等,就会采用DM9000来实现联网功能。DM9000提供了一个类似 SRAM 的访问接口,主控 CPU 通过这个接口即可与DM9000 进行通信,DM9000 就是一个 MAC+PHY 芯片。这个方案就相当于外部 MAC+外部PHY,那么 I.MX6U 这样的内部 MAC+PHY 芯片与 DM9000 方案比有什么优势吗?

那优势大了去了!首先就是通信效率和速度,一般 SOC 内部的MAC是带有一个专用DMA 的,专门用于处理网络数据包,采用SRAM来读写DM9000的速度是压根就没法和内部 MAC+外部 PHY 芯片的速度比。采用外部 DM9000 完全是无奈之举,谁让 2440,4412 这些芯片内部没有以太网外设呢,现在又想用有线网络,没有办法只能找个 DM9000 的方案。从这里也可以看出,三星的 2440、4412 这些芯片设计之初就不是给工业产品用的,他们是给消费类电子使用的,比如手机、平板等,手机或平板要上网,可以通过 WIFI 或者 4G,我是没有见过哪个手机或者平板上网是要接根网线的。正点原子的 I.MX6U-ALPHA 开发板也可以通过 WIFI 或者 4G 上网。

I.MX6UL-MINI有一个网络接口 ENET2,使用 LAN8720A 作为 PHY 芯片。NXP 官方的I.MX6ULL EVK 开发板使用 KSZ8081 这颗 PHY 芯片,LAN8720A 相比 KSZ8081 具有体积小、外围器件少、价格便宜等优点。直接使用 KSZ8081 固然可以,但是我们在实际的产品中不一定会使用 KSZ8081,有时候为了降低成本会选择其他的 PHY 芯片,这个时候就有个问题:换了PHY 芯片以后网络驱动怎么办?为此,正点原子的 I.MX6U开发板将 ENET2的PHY 换成了 LAN8720A,这样就可以给大家讲解更换 PHY 芯片以后如何调整网络驱动,使网络工作正常。


ENET2的网络PHY芯片为LAN8720A,通过RMII接口与I.MX6ULL 相连,正点原子I.MX6U-MINI开发板的 ENET2引脚与 NXP 官方的 I.MX6ULL EVK 开发板基本一样,唯独复位引脚不同。从图可以看出,正点原子 I.MX6U-MINI开发板的 ENET2 复位引脚ENET2_RST 接到了 I.M6ULL 的 SNVS_TAMPER8 这个引脚上。LAN8720A 内部是有寄存器的,I.MX6ULL 会读取 LAN8720 内部寄存器来判断当前的物理链接状态、连接速度(10M 还是 100M)和双工状态(半双工还是全双工)。

I.MX6ULL通过MDIO接口来读取 PHY 芯片的内部寄存器,MDIO 接口有两个引脚,ENET_MDC 和 ENET_MDIO,ENET_MDC 提供时钟,ENET_MDIO 进行数据传输。一个 MIDO 接口可以管理 32 个 PHY 芯片,同一个 MDIO 接口下的这些 PHY 使用不同的器件地址来做区分,MIDO 接口通过不同的器件地址即可访问到相应的 PHY 芯片

注意:LAN8720A 可以通过PHYAD0引脚来配置,该引脚与RXER引脚复用,芯片内部自带下拉电阻,当硬复位结束后, LAN8720A会读取该引脚电平,作为器件的SMI 地址,接下拉电阻时(浮空也可以,因为芯片内部自带了下拉电阻),设置 SMI 地址为 0,当外接上拉电阻后,可以设置为 1。对于正点原子mx6ull-mini板来说LAN8720芯片第10引脚RXER接了上拉电阻,所以PHY芯片地址为1。对于正点原子stm32f407板来说LAN8720芯片第10引脚RXER悬空,所以PHY芯片地址为0。

I.MX6U-MINI开发板ENET2上连接的LAN8720A器件地址为0X1,所示我们要修改 ENET2网络驱动的话重点就三点:

  • ①、ENET2 的复位引脚,从上图可以看出,ENET2 的复位引脚ENET2_RST接到了I.MX6ULL 的 SNVS_TAMPER8 上。
  • ②、ENET2 所使用的 PHY 芯片器件地址,从图可以看出,PHY 器件地址为0X1。

2、网络 PHY 地址修改
首先修改uboot中的ENET2 的 PHY 地址和驱动,打开mx6ull_alientek_emmc.h这个文件,找到如下代码:

#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 0x2
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_MICREL
346 #endif

第331行的宏CONFIG_FEC_ENET_DEV用于选择使用哪个网口,默认为1,也就是选择ENET2。第 335 行为ENET1的PHY地址,默认是 0X2,第 339 行为ENET2 的 PHY地址,默认为0x1。根据前面的分析可知,正点原子的I.MX6U-MINI开发板ENET1的PHY地址为0X0,ENET2的PHY地址为 0X1,所以需要将第335行的宏CONFIG_FEC_MXC_PHYADDR改为0x0

第345行定了一个宏CONFIG_PHY_MICREL,此宏用于使能uboot中 Micrel 公司的PHY驱动,KSZ8081这颗PHY芯片就是Micrel公司生产的,不过Micrel已经被Microchip收购了。如果要使用LAN8720A,那么就得将CONFIG_PHY_MICREL改为CONFIG_PHY_SMSC,也就是使能 uboot 中的SMSC公司中的PHY驱动,因为LAN8720A就是SMSC公司生产的。所以示例代码有三处要修改:

  • ①、修改 ENET1 网络 PHY 的地址。
  • ②、修改 ENET2 网络 PHY 的地址。
  • ③、使能 SMSC 公司的 PHY 驱动。

修改后的网络 PHY 地址参数如下所示:

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
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
346 #endif

3 、删除 uboot 中 74LV595 的驱动代码

boot 中网络 PHY 芯片地址修改完成以后就是网络复位引脚的驱动修改了,因为 NXP 官方I.MX6ULL EVK 开发板使用 74LV595 来扩展 IO,两个网络的复位引脚就是由 74LV595 来控制的。正点原子的 I.MX6U-ALPHA 开发板并没有使用 74LV595,所以需要修改。ENET1 的复位引脚连接到SNVS_TAMPER7 上,对应 GPIO5_IO07,ENET2 的复位引脚连接到 SNVS_TAMPER8 上,对应 GPIO5_IO08。详细过程参考
【正点原子】i.MX6U嵌入式linux驱动开发指南v1.5.pdf的33.2.7小结

4 、添加 I.MX6U-MINI开发板网络复位引脚驱动

ENET1 和 ENET2 的复位 IO 初始化,将这两个 IO 设置为输出并且硬件复位一下 LAN8720A,这个硬件复位很重要!否则可能导致 uboot 无法识别 LAN8720A。

详细过程参考
【正点原子】i.MX6U嵌入式linux驱动开发指南v1.5.pdf的33.2.7小结

5 、修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link

大功基本上告成,还差最后一步,uboot中的LAN8720A驱动有点问题,打开文件drivers/net/phy/phy.c,找到函数genphy_update_link,这是个通用 PHY 驱动函数,此函数用于更新PHY的连接状态和速度。使用 LAN8720A 的时候需要在此函数中添加一些代码。至此网络的复位引脚驱动修改完成,重新编译uboot,然后将u-boot.bin 烧写到SD卡中并启动。


从图中可以看到Net: FEC1这一行,提示当前使用的 FEC1 这个网口,也就是 ENET2。在 uboot 中使用网络之前要先设置几个环境变量,命令如下:

setenv ipaddr 192.168.10.50//开发板 IP 地址
setenv ethaddr 00:04:9f:04:d2:35 //开发板网卡 MAC 地址
setenv gatewayip 192.168.10.1 //开发板默认网关
setenv netmask 255.255.255.0  //开发板子网掩码
setenv serverip 192.168.10.100  //服务器地址,也就是 Ubuntu 地址
saveenv //保存环境变量

设置好环境变量以后就可以在uboot中使用网络了,用网线将 I.MX6U-MINI上的 ENET2与电脑或者路由器连接起来,保证开发板和电脑在同一个网段内,通过 ping 命令来测试一下网络连接,命令如下:

ping 192.168.10.100


从图可以看出,有host 192.168.10.100is alive这句,说明 ping 主机成功,说明ENET2网络工作正常。

如果想测试一下ENET1的网络是否正常工作,打开mx6ull_alientek_emmc.h,将 CONFIG_FEC_ENET_DEV 改为 0,然后重新编译一下 uboot 并烧写到 SD 卡中重启。重启开
发板,uboot 输出信息中看到Net: FEC0这一行,提示当前使用的 FEC0这个网口,也就是 ENET1。不过MINI板板子上只有一个网口就是只使用了ENET2。

8、其他需要修改的地方

在 uboot 启动信息中会有Board: MX6ULL 14x14 EVK这一句,也就是说板子名字为MX6ULL 14x14 EVK,要将其改为我们所使用的板子名字,比如MX6ULL ALIENTEK ZHIGUOXIN。打开文件 mx6ull_alientek_emmc.c,找到函数checkboard,将其改为如下所示内容:

int checkboard(void)

	if (is_mx6ull_9x9_evk())
		puts("Board: MX6ULL 9x9 EVK\\n");
	else
		puts("Board: MX6ULL ALIENTEK ZHIGUOXIN\\n");
	return 0;


至此uboot的驱动部分就修改完成了,uboot移植也完成了,uboot的最终目的就是启动Linux内核,所以需要通过启动Linux内核来判断uboot移植是否成功。在启动 Linux 内核之前我们先来学习两个重要的环境变量bootcmd和bootargs。

环境变量 bootcmd

bootcmd保存着uboot默认命令,uboot倒计时结束以后就会执行bootcmd中的命令。这些命令一般都是用来启动 Linux内核的(比如读取 EMMC 或者 NAND Flash 中的 Linux 内核镜像文件和设备树文件到 DRAM 中,然后启动 Linux 内核)。可以在uboot 启动以后进入命令行设置 bootcmd 环境变量的值。如果 EMMC 或者 NAND 中没有保存 bootcmd 的值,那么 uboot 就会使用默认的值,板子第一次运行 uboot 的时候都会使用默认值来设置bootcmd环境变量

以上是关于正点原子I.MX6U-MINIu-boot过程移植详解的主要内容,如果未能解决你的问题,请参考以下文章

正点原子I.MX6U-MINI移植篇kernel移植过程详解

正点原子I.MX6U-MINI移植篇u-boot移植过程详解

正点原子I.MX6U-MINI移植篇rootfs移植过程详解

正点原子I.MX6U-MINI移植篇rootfs移植过程详解

正点原子I.MX6U-MINI移植篇Ubuntu-base根文件系统移植构建过程详解

正点原子I.MX6U-MINI移植篇Ubuntu-base根文件系统移植构建过程详解