一、源码下载
本文直接使用正点原子提供的 uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2 源码。也可以根据下文提示去NXP官网下载。
以i.MX 6ULL EVK为例
半导体厂商官网一般会提供uboot源码,但是NXP官网似乎没有提供uboot下载,可依照以下图片提示找到源码下载地址。
我选的版本是6.1.1
下载地址:https://github.com/nxp-imx/uboot-imx
二、配置
2.1 配置文件
解压后进入configs目录,复制一份自己的配置文件。
cd configs
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_lyh_emmc_defconfig
vi mx6ull_lyh_emmc_defconfig 改为下面字段
1 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_lyh_emmc/imximage.cfg,MX6ULL_EVK_EMMC_RE_WORK"
2 CONFIG_ARM=y
3 CONFIG_ARCH_MX6=y
4 CONFIG_TARGET_MX6UL_LYH_EMMC=y
5 CONFIG_CMD_GPIO=y
2.2 头文件
cp include/configs/mx6ullevk.h include/configs/mx6ull_lyh_emmc.h
拷贝完成以后将:
#ifndef __MX6ULLEVK_CONFIG_H
#define __MX6ULLEVK_CONFIG_H
改为:
#ifndef __MX6ULL_LYH_EMMC_CONFIG_H
#define __MX6ULL_LYH_EMMC_CONFIG_H
mx6ull_lyh_emmc.h 里面有很多宏定义,这些宏定义基本用于配置 uboot,也有一些 I.MX6ULL 的配置项目。如果我们自己要想使能或者禁止 uboot 的某些功能,那就在mx6ull_lyh_emmc.h 里面做修改即可。
mx6ull_lyh_emmc.h 文件中基本都是“
CONFIG_
”开头
的宏定义,这也说明
mx6ull_lyh_emmc.h
文件的主要功能就是配置或者裁剪
uboot
。如果需
要某个功能的话就在里面添加这个功能对应的
CONFIG_XXX
宏即可,如果不需要某个功能的
话就删除掉对应的宏即可。
2.3板级文件夹
cd board/freescale/
cp mx6ullevk/ -r mx6ull_lyh_emmc
cd mx6ull_lyh_emmc
mv mx6ullevk.c mx6ull_lyh_emmc.c
1、修改 mx6ull_lyh_emmc 目录下的 Makefile 文件,修改obj-y
obj
-
y
:=
mx6ull_lyh_emmc
.
o
2
、修改
imximage.cfg 文件,PLUGIN
PLUGIN board/freescale/mx6ull_lyh_emmc/plugin.bin 0x00907000
3
、修改
Kconfig
文件
1
if
TARGET_MX6ULL_LYH_EMMC
2
3
config SYS_BOARD
4
default
"mx6ull_lyh_emmc"
5
6
config SYS_VENDOR
7
default
"freescale"
8
9
config SYS_SOC
10
default
"mx6"
11
12
config SYS_CONFIG_NAME
13
default
"mx6ull_lyh_emmc"
14
15
endif
1
MX6ULL_ALIENTEK_EMMC BOARD
2
M
:
Peng Fan
<
peng
.
fan@nxp
.
com
>
3
S
:
Maintained
4
F
:
board
/
freescale
/
mx6ull_alientek_emmc
/
5
F
:
include
/
configs
/
mx6ull_alientek_emmc
.
h
2.4图形化配置
uboot
是支持图形界面配置,关于
uboot
的图形界面配置下一章会详细的讲解。修改文件 arch/arm/cpu/armv7/mx6/Kconfig
,在
207
行加入如下内容:
1
config TARGET_MX6ULL_LYH_EMMC
2
bool
"Support mx6ull_lyh_emmc"
3
select MX6ULL
4
select DM
5
select DM_THERMAL
在最后一行的
endif
的前一行添加如下内容:
1
source
"board/freescale/mx6ull_lyh_emmc/Kconfig"
到此为止,I.MX6U-ALPHA 开发板就已经添加到 uboot 中了,接下来就是编译这个新添加的开发板。
三、编译
vi mx6ull_lyh_emmc.sh
1
#
!
/bin/bash
2
make ARCH
=
arm CROSS_COMPILE
=
arm
-
linux
-
gnueabihf
-
distclean
3
make ARCH
=
arm CROSS_COMPILE
=
arm
-
linux
-
gnueabihf
- (
加空格
)
mx6ull_lyh_emmc_defconfig
4
make V
=
1
ARCH
=
arm CROSS_COMPILE
=
arm
-
linux
-
gnueabihf
- -
j6
chmod 777 mx6ull_lyh_emmc.sh//
给予可执行权限,一次即可
./mx6ull_lyh_emmc.sh//
运行脚本编译
uboot
编译成功如下图:
编译完成以后就使用
imxdownload
将新编译出来的
u-boot.bin
烧写到
SD
卡中测试。
./imxdownload u-boot.bin /dev/sdb //
烧写到
SD
卡,不能烧写到
/dev/sda
或
sda1
设备里面!
默认
uboot
中的
LCD
驱动和网络驱动在正点原子的
I.MX6U-ALPHA
开发板上是有问题的,需要修改。
四、驱动修改
4.1 lcd驱动
一般 uboot
中修改驱动基本都是在
xxx.h
和
xxx.c
这两个文件中进行的,
xxx
为板子名称,
比如
mx6ull_lyh_emmc.h
和
mx6ull_lyh_emmc.c
这两个文件。
一般修改
LCD
驱动重点注意以下几点:
①、
LCD
所使用的
GPIO
,查看
uboot
中
LCD
的
IO
配置是否正确。
②、
LCD
背光引脚
GPIO
的配置。
③、
LCD
配置参数是否正确。
正点原子的 I.MX6U-ALPHA
开发板
LCD
原理图和
NXP
官方
I.MX6ULL
开发板一致,也
就是
LCD
的
IO
和背光
IO
都一样的,所以
IO
部分就不用修改了。需要修改的之后
LCD
参数,
打开文件
mx6ull_lyh_emmc.c
,找到如下图所示内容:
vi board/freescale/mx6ull_lyh_emmc/mx6ull_lyh_emmc.c
定义了一个变量 displays
,类型为
display_info_t
,这个结构体是
LCD 信息结构体,其中包括了
LCD
的分辨率,像素格式,
LCD
的各个参数等。
display_info_t
定义
在文件
arch/arm/include/asm/imx-common/video.h
中。
pixclock=(1/33300000)*10^12=30030
vi include/configs/mx6ull_lyh_emmc.h
打开
mx6ull_lyh_emmc.h
,找到所有如下语句:
panel=TFT43AB
将其改为:
panel=ATK7084
重新编译uboot,然后烧录到开发板
重启以后 LCD
驱动一般就会工作正常了,
LCD
上回显示
NXP
的
logo
。但是有可能会遇到
LCD
并没有工作,还是黑屏,这是什么原因呢?在
uboot
命令模式输入“
print
”来查看环境变
量
panel
的值,会发现
panel
的值要是
TFT43AB(
或其他的,反正不是
ATK7084)
这是因为之前有将环境变量保存到 EMMC
中,
uboot
启动以后会先从
EMMC
中读取环境
变量,如果
EMMC
中没有环境变量的话才会使用
mx6ull_lyh_emmc.h
中的默认环境变量。
如果
EMMC
中的环境变量
panel 不等于 ATK7084,那么 LCD
显示肯定不正常,我们只需要在
uboot
中修改
panel 的值为 ATK7084 即可,在
uboot
的命令模式下输入如下命令:
setenv panel ATK7084
saveenv
然后重启uboot即可。
4.2 网络驱动
4.2.1 开发板网络简介
I.MX6UL/ULL 内部有个以太网
MAC
外设,也就是
ENET
,需要外接一个
PHY
芯片来实
现网络通信功能,也就是内部
MAC+
外部
PHY
芯片的方案。
ENET1 的网络
PHY
芯片为
LAN8720A
,通过
RMII
接口与
I.MX6ULL
相连,正点原子
I.MX6U-ALPHA
开发板的
ENET1
引脚与
NXP
官方的
I.MX6ULL EVK
开发板基本一样,唯独
复位引脚不同。从图
33.2.7.1
可以看出,正点原子
I.MX6U-ALPHA
开发板的
ENET1
复位引脚
ENET1_RST
接到了
I.M6ULL
的
SNVS_TAMPER7
这个引脚上。
LAN8720A
内部是有寄存器的,
I.MX6ULL
会读取
LAN8720
内部寄存器来判断当前的物
理链接状态、连接速度
(10M
还是
100M)
和双工状态
(
半双工还是全双工
)
。
I.MX6ULL
通过
MDIO
接口来读取
PHY
芯片的内部寄存器,
MDIO
接口有两个引脚,
ENET_MDC
和
ENET_MDIO
,
ENET_MDC
提供时钟,
ENET_MDIO
进行数据传输。一个
MDIO
接口可以管理
32
个
PHY
芯
片,同一个
MDIO
接口下的这些
PHY
使用不同的器件地址来做区分,
MIDO
接口通过不同的
器件地址即可访问到相应的
PHY
芯片。
I.MX6U-ALPHA
开发板
ENET1
上连接的
LAN8720A
器件地址为
0X0
,所示我们要修改
ENET1
网络驱动的话重点就三点:
①、
ENET1
复位引脚初始化。
②、
LAN8720A
的器件
ID
。
③、
LAN8720
驱动
关于
ENET2
网络驱动的修改也注意一下三点:
①、
ENET2
的复位引脚,从图
33.2.7.2
可以看出,
ENET2
的复位引脚
ENET2_RST
接到了I.MX6ULL
的
SNVS_TAMPER8
上。
②、
ENET2
所使用的
PHY
芯片器件地址,从图
33.2.7.2
可以看出,
PHY
器件地址为
0X1
。
③、
LAN8720
驱动,
ENET1
和
ENET2
都使用的
LAN8720
,所以驱动肯定是一样的。
4.2.2 网络phy地址修改
vi include/configs/mx6ull_lyh_emmc.h
找到#define CONFIG_FEC_MXC_PHYADDR
修改后:
#define CONFIG_PHY_SMSC
4.2.3 删除 uboot 中 74LV595 的驱动代码
vi board/freescale/mx6ull_lyh_emmc/mx6ull_lyh_emmc.c
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)
因为 NXP
官方I.MX6ULL EVK
开发板使用
74LV595
来扩展
IO
,两个网络的复位引脚就是由
74LV595
来控制
的。正点原子的
I.MX6U-ALPHA
开发板并没有使用
74LV595。
改为:
#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)
2、找到:static iomux_v3_cfg_t const iox_pads[]
ENET1 的复位引脚连接到
SNVS_TAMPER7
上,对应
GPIO5_IO07
,
ENET2
的复位引脚连接到
SNVS_TAMPER8
上,对应
GPIO5_IO08
。
上图是 74LV595 的 IO 配置参数结构体,将其删除掉。
3、继续在mx6ull_lyh_emmc.c 中找到函数 iox74lv_init 和 iox74lv_set。
iox74lv_init 函数是
74LV595
的初始化函数,
iox74lv_set
函数用于控制
74LV595
的
IO
输出
电平,将这两个函数全部删除掉!
4、找到 board_init 函数,此函数是板子初始化函数,会被 board_init_r 调用,board_init 会调用 imx_iomux_v3_setup_multiple_pads 和 iox74lv_init 这两个函数来初始化 74lv595 的 GPIO,将这两行删除掉。
4.2.4 添加 I.MX6U-ALPHA 开发板网络复位引脚驱动
在 mx6ull_lyh_emmc.c 中找到:
static
iomux_v3_cfg_t
const
fec1_pads
[] ,
结构体数组
fec1_pads
和
fec2_pads
是
ENET1
和
ENET2
这两个网口的
IO
配置参数,在这两个数组中添加两个网口的复位
IO
配置参数
MX6_PAD_SNVS_TAMPER7__GPIO5_IO07
|
MUX_PAD_CTRL
(
NO_PAD_CTRL
),
MX6_PAD_SNVS_TAMPER8__GPIO5_IO08
|
MUX_PAD_CTRL
(
NO_PAD_CTRL
),
继续找到:
static void
setup_iomux_fec
(
int
fec_id
)
,函数
setup_iomux_fec
就是根据
fec1_pads
和
fec2_pads
这两个网络
IO
配置数组来初始化
I.MX6ULL
的网络
IO
。我们需要在其中添加网络复位
IO
的初始化代码,并且复位一下
PHY
芯
片。
gpio_direction_output
(
ENET1_RESET
,
1
);
gpio_set_value
(
ENET1_RESET
,
0
);
mdelay
(
20
);
gpio_set_value
(
ENET1_RESET
,
1
);
gpio_direction_output
(
ENET2_RESET
,
1
);
gpio_set_value
(
ENET2_RESET
,
0
);
mdelay
(
20
);
gpio_set_value
(
ENET2_RESET
,
1
);
4.2.5 修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link
大功基本上告成,还差最后一步,uboot
中的
LAN8720A
驱动有点问题,打开文件
drivers/net/phy/phy.c
,找到函数
genphy_update_link
,这是个通用
PHY
驱动函数,此函数用于更
新
PHY
的连接状态和速度。使用
LAN8720A
的时候需要在此函数中添加一些代码。
#ifdef CONFIG_PHY_SMSC
static 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
五、测试
烧写测试
设置下 ip 地址等信息。
setenv ipaddr 192.168.137.9 //开发板 IP 地址
setenv ethaddr b8:ae:1d:01:00:02 //开发板网卡
MAC
地址
setenv gatewayip 192.168.137.1 //开发板默认网关
setenv netmask 255.255.255.0 //开发板子网掩码
setenv serverip 192.168.137.10 //服务器地址,也就是 Ubuntu 地址
saveenv //保存环境变量
ping一下虚拟机ip,成功。