uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)

一、NXP官方uboot

1. 下载

NXP官方uboot仓库地址为:https://github.com/Freescale/u-boot-fslc。

这里为了保持版本统一,使用正点原子资料包中提供的原厂linuxuboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2(版本是2016.03)。

2. 编译

设置临时环境变量:

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-

清理构建:

make distclean

查看uboot/configs目录下imx6ull相关的单板:

NXP官方EVK支持nand和emmc两种,因为我手头的开发板是emmc的,所以这里也选择emmc版本的EVK。

配置单板:

make mx6ull_14x14_evk_emmc_defconfig

配置好之后编译:

make

编译成功之后可以看到三个uboot的文件,作用如下。

  • uboot:可执行文件
  • uboot.bin:bin格式可执行文件
  • uboot.imx:适用于NXP工具烧写的可执行文件

3. 烧写到SD卡

imxdownload u-boot.bin /dev/sdb

4. 执行结果分析

将SD卡插入板子,选择从SD卡启动,查看串口日志:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第1张图片
(1)uboot正常启动;
(2)uboot正确识别到DDR,大小为512MB;
(3)检查 SD 卡和EMMC是否正常:

// 列出当前mmc设备
mmc list

// 查看设备0的信息
mmc dev 0
mmc info

// 查看设备1的信息
mmc dev 1
mmc info

SD卡大小16GB,正常:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第2张图片
EMMC大小为8GB,正常:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第3张图片
(4)LCD显示设备检查

uboot打印日志中提示LCD显示设备是Display: TFT43AB (480x272),这里我实际连接的是正点原子7寸RGB屏幕,不匹配,所以LCD无显示。

(5)网络设备检查

uboot打印日志中提示未找到网络设备:

Booting from net ...
No ethernet found.
No ethernet found.

接下来,我们就基于NXP官方提供的uboot,针对正点原子imx6ull开发板进行一些配置参数的修改,修复LCD和网络问题

二、移植uboot

1. 新建单板

(1)新建单板目录,复制官方EVK的单板目录:

cd board/freescale
cp -rf mx6ullevk/ mx6ullatk

进入新建的目录,进行修改。
① 重命名c文件:

cd mx6ullatk/
mv mx6ullevk.c mx6ullatk.c

② 修改Makefile:

obj-y  := mx6ullatk.o

③ 修改imximage.bin文件:

#ifdef CONFIG_USE_PLUGIN
/*PLUGIN    plugin-binary-file    IRAM_FREE_START_ADDR*/
PLUGIN	board/freescale/mx6ullatk/plugin.bin 0x00907000
#else

修改Kconfig文件:

if TARGET_MX6ULL_14X14_ATK

config SYS_BOARD
	default "mx6ullatk"

config SYS_VENDOR
	default "freescale"

config SYS_CONFIG_NAME
	default "mx6ullatk"

endif

修改 MAINTAINERS 文件:

MX6ULLATK BOARD
M:	Mculover666 <[email protected]>
S:	Maintained
F:	board/freescale/mx6ullatk/
F:	include/configs/mx6ullatk.h
F:	configs/mx6ull_14x14_atk_defconfig

(2)新建开发板默认配置文件:

cd configs/
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_14x14_atk_emmc_defconfig

修改该文件中的下面两行内容:

CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ullatk/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_TARGET_MX6ULL_14X14_ATK=y

(3)新建开发板头文件:

cd include/configs
cp mx6ullevk.h mx6ullatk.h

修改头文件中的内容:

#ifndef __MX6ULLATK_CONFIG_H
#define __MX6ULLATK_CONFIG_H

将文件最后关于android的支持去除:

// #if defined(CONFIG_ANDROID_SUPPORT)
// #include "mx6ullevk_android.h"
// #endif

(4)在menuconfig中添加新的单板

仿照其它单板文件,添加:

config TARGET_MX6ULL_14X14_ATK
	bool "Support mx6ull_14x14_atk"
	select MX6ULL
	select DM
	select DM_THERMAL

在临近末尾处仿照添加:

source "board/freescale/mx6ullatk/Kconfig"

(5)新的单板编译测试

至此,添加一个新的单板到uboot中完成,编译测试:

make distclean
make mx6ull_14x14_atk_emmc_defconfig
make

编译成功后,将bin烧写到SD卡,启动查看效果:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第4张图片
和原厂uboot运行效果一样,新建单板成功。

2. 修改适配驱动

uboot中修改驱动配置在xxx.hxxx.c两个文件中,xxx为单板名称

2.1. 修改LCD驱动

检查LCD驱动的思路为
① 检查LCD引脚配置
② 检查屏幕参数配置

① 检查LCD引脚配置:查看原理图,本文所使用的开发板和官方开发板的LCD引脚相同,无需修改;

② 检查屏幕参数配置

本文中使用的是正点原子7寸RGB屏幕,在board/freescale/mx6ullatk/mx6ullatk.c文件中,修改屏幕默认参数配置如下:

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",
		.xres           = 1024,
		.yres           = 600,
		.pixclock       = 19351,
		.left_margin    = 140,
		.right_margin   = 160,
		.upper_margin   = 20,
		.lower_margin   = 12,
		.hsync_len      = 20,
		.vsync_len      = 3,
		.sync           = 0,
		.vmode          = FB_VMODE_NONINTERLACED
} } };

接着在include/configs/mx6ullatk.h文件中,修改uboot默认环境变量设置:

"panel=TFT7016\0" \

修改之后,重新编译uboot,烧写到SD卡中运行:

uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第5张图片
此时,LCD已经成功点亮,显示NXP logo:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第6张图片

2.2. 修改网络驱动

IMX6ULL有两个ENET外设,本文所使用的开发板与官方EVK开发板的区别在于:使用RMII接口连接LAN8720A PHY 芯片,且复位引脚不同,其余引脚相同。

所以修改网络驱动的思路为:

  • ① 修改PHY器件地址
  • ② 修改复位引脚初始化

ENET1原理图如下:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第7张图片
ENET2原理图如下:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第8张图片
两个复位引脚分别对应的引脚如下表:

信号 引脚
ENET1_RST SNVS_TAMPER7/GPIO5_IO07
ENET2_RST SNVS_TAMPER8/GPIO5_IO08

修改PHY芯片器件地址

include/configs/mx6ullatk.h文件中修改两个PHY芯片的器件地址:

#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE			ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR          0x0
#define CONFIG_FEC_XCV_TYPE             RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE			ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR		0x1
#define CONFIG_FEC_XCV_TYPE		RMII
#endif

修改复位引脚驱动

复位引脚在EVK开发板上被74LV595使用,如图:

74LV595是串行转并行的一个芯片,通常用来扩展IO引脚,在本文所使用的开发板上未使用,所以在board/freescale/mx6ullatk/mx6ullatk.cinclude/configs/mx6ullatk.h文件中去掉相关代码,去除之后一定要确保编译成功才可以进行后续工作。

接下来在mx6ullatk.c中添加复位引脚配置:

#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)

/*
 * 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),

	/* RST */
	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),
	
	/* RST */
	MX6_PAD_SNVS_TAMPER7__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
};

再添加一个硬复位函数,在ETH初始化的时候,硬件复位外部PHY芯片:

static void board_eth_hard_reset(int fec_id)
{
     
	if (fec_id == 0) {
     
		gpio_direction_output(ENET1_RESET, 1);
		gpio_set_value(ENET1_RESET, 0);
		mdelay(20);
		gpio_set_value(ENET1_RESET, 1);
	} else {
     
		gpio_direction_output(ENET2_RESET, 1);
		gpio_set_value(ENET2_RESET, 0);
		mdelay(20);
		gpio_set_value(ENET2_RESET, 1);
	}
}

int board_eth_init(bd_t *bis)
{
     
	setup_iomux_fec(CONFIG_FEC_ENET_DEV);
	board_eth_hard_reset(CONFIG_FEC_ENET_DEV);

	return fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
				       CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
}

编译uboot,下载到SD卡中,运行查看日志:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第9张图片
代码中搜索 "address not set"来定位问题,很快就找到根源了:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第10张图片
uboot从环境变量中加载网卡MAC地址,结果MAC地址为空,所以输出错误提示。

解决方案非常简单,在uboot中设置一下MAC地址即可:

setenv ethaddr 00:04:9f:04:d2:35
saveenv

重启之后可以看到无错误提示,设置ip地址、网关地址、子网掩码:

setenv ipaddr 192.168.1.101
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
saveenv

接着ping开机主机测试:

ping 192.168.1.100

报如下错误:

这个问题实在是太难定位了,查询正点原子移植资料寻求解决办法,修复LAN8720A的代码,编辑drivers/net/phy/phy.c文件中的函数 genphy_update_link,在函数刚进入时添加如下代码:

#ifdef CONFIG_PHY_SMSC
	static int lan8720_flag = 0;
	int bmcr_reg;

	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	/* CONFIG_PHY_SMSC */

重新编译,烧写,测试结果如下:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第11张图片
同理,在include/configs/mx6ullatk.h文件中将默认网卡设为0,测试ETH1是否正常:

#define CONFIG_FEC_ENET_DEV		0

重新编译uboot、烧写,将网线查到ETH1网口上,测试结果如下:uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第12张图片

3. 修改启动打印信息

修改board/freescale/mx6ullatk/mx6ullatk.c文件:

int checkboard(void)
{
     
	puts("Board: i.MX6ULL ATK ALPHA\n");

	return 0;
}

uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第13张图片

三、使用uboot启动内核

1. 从emmc启动

检查emmc中是否有内核文件和设备树文件:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第14张图片
查看uboot传递给kernel的启动参数:

这个和本文所使用的开发板出厂烧录的kernel不一致,修改一下保存:

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv

(1)手动启动

手动加载内核到内存中:

mmc dev 1
fatload mmc 1:1 80800000 zImage

uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第15张图片
加载设备树到内存中:

fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb

启动内核:

bootz 80800000 - 83000000

可以看到内核成功启动。

(2)使用bootcmd启动

查看nxp uboot官方提供的bootcmd值:

不使用这个,直接将上述手动启动的命令写为一条命令,放在bootcmd环境变量中:

setenv bootcmd 'mmc dev 1;fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb;bootz 80800000 - 83000000;'
saveenv

设置完成后,直接启动:

boot

可以看到内核成功启动:
uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第16张图片

2. 从网络启动

确保tftp服务正常,且内核和设备树文件已放置在tftp根目录。


设置服务器ip地址:

setenv serverip 192.168.1.102

设置启动参数:

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'

保存环境变量:

saveenv

下载内核到内存中:

tftp 80800000 zImag

uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第17张图片
下载设备树到内存中:

tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb

uboot | 移植NXP官方uboot到imx6ull开发板(2016.03)_第18张图片
启动内核:

bootz 80800000 - 83000000

启动成功。

你可能感兴趣的:(#,uboot研读笔记,linux,uboot)