uboot移植

版权声明:此博客为个人博客,不涉及商业用途,仅提供学习参考,内容均来自个人原创以及互联网转载和摘录。 如果本博客侵犯了您的权益,请联系本人,本人将会在第一时间删除侵权文章! https://blog.csdn.net/qq_22902919/article/details/82883644

参考i.MX_6_BSP_Porting_Guide.pdf手册,下载u-boot源码,以下是文档和源码链接。
fsl_yocto-L4.1.15_2.0.0-ga.tar.gz
uboot-imx-imx_v2016.03_4.1.15_2.0.0_ga

  1. 板级头文件
cp include/configs/mx6sabresd.h  include/configs/mx6q_tqcorec.h
  1. 选择配置文件
vim  arch/arm/cpu/armv7/mx6/Kconfig +100
	config TARGET_MX6Q_TQCOREC
	        bool "mx6q_tqcorec"
	        select SUPPORT_SPI
	        select DM
	        select DM_THERMAL

	source "board/freescale/mx6q_tqcorec/Kconfig"
  1. 板级文件
cp -R board/freescale/mx6sabresd  board/freescale/mx6q_tqcorec
cd board/freescale/mx6q_tqcorec/
mv mx6sabresd.c mx6q_tqcorec.c
vim Makefile
	  obj-y  := mx6q_tqcorec.o
vim Kconfig
	if TARGET_MX6Q_TQCOREC

	config SYS_BOARD
	        default "mx6q_tqcorec"

	config SYS_VENDOR
	        default "freescale"

	config SYS_CONFIG_NAME
	        default "mx6q_tqcorec"

	endif
  1. 默认配置文件
vim configs/mx6q_tqcorec_defconfig
	CONFIG_ARM=y
	CONFIG_ARCH_MX6=y
	CONFIG_TARGET_MX6Q_TQCOREC=y
	CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6q_tqcorec/mx6q_4x_mt41j128.cfg,MX6Q,SYS_USE_SPINOR"
	CONFIG_CMD_GPIO=y

其中内存参数是由mx6q_4x_mt41j128.cfg配置文件决定,把天嵌官方文件拷贝过来,或者但采用飞思卡尔的工具配置DCD,下载DDR_Stress_Tester_V1.0.3.zip和I.MX6DQSDL
DDR3 Script Aid V0.10.xlsx两个工具。

  1. 串口

查看TQIMX6Q的原理图可知,TQIMX6Q的UART1的TXD和RXD分别接到了UART1_TXD(SD3_DAT7)和UART1_RXD(SD3_DAT6)两个管脚上.

vim board/freescale/mx6q_tqcorec/mx6q_tqcorec.c 
	static iomux_v3_cfg_t const uart1_pads[] = {
        //MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
        //MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
        MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
        MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
	};

由于MX6_PAD_SD3_DAT7、MX6_PAD_SD3_DAT6已经被USDHC3占用

static iomux_v3_cfg_t const usdhc3_pads[] = {
 //      MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 //      MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 //      MX6_PAD_NANDF_D0__GPIO2_IO00    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD      */
 };
  1. SD卡槽

sd卡槽使用的是USDHC2控制器,并且与sabresd不同的是 该SD CARD电路的CD引脚使用的是GPIO_4.

static iomux_v3_cfg_t const usdhc2_pads[] = {
//MX6_PAD_NANDF_D2__GPIO2_IO02    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
MX6_PAD_GPIO_4__GPIO1_IO04      | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
};

sd卡槽cd引脚宏定义:

//#define USDHC2_CD_GPIO        IMX_GPIO_NR(2, 2)
//#define USDHC3_CD_GPIO        IMX_GPIO_NR(2, 0)
#define USDHC2_CD_GPIO  IMX_GPIO_NR(1, 4)

int board_mmc_getcd(struct mmc *mmc)
{
......
//ret = !gpio_get_value(USDHC3_CD_GPIO);
}

int board_mmc_init(bd_t *bis)
{
......
//gpio_direction_input(USDHC3_CD_GPIO);
}

查看原理图及IMX6Q芯片手册可以发现UART1和UART2的TXD和RXD与usdhc3_pads的管脚是复用的,因此,MMC初始化时不能将UART相关的引脚初始化为MMC相关引脚,由于这块开发板上没有引出usdhc3,所以不会影响开发板的其它功能。

static iomux_v3_cfg_t const usdhc3_pads[] = {
//MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
//MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
}

static const struct boot_mode board_boot_modes[] = {
......
//{"sd3",  MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
}
  1. 编译
make mx6q_tqcorec_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
  1. 烧写sd卡
sudo dd if=/dev/zero of=/dev/sdb bs=512 seek=2 count=512
sudo dd if=u-boot.imx of=/dev/sdb bs=512 seek=2
  1. 错误以及解决方法

运行开发板报错,以下是log文件:

U-Boot 2016.03 (Aug 27 2018 - 17:38:55 +0800)

CPU:   Freescale i.MX6Q rev1.2 996 MHz (running at 792 MHz)
CPU:   Extended Commercial temperature grade (-20C to 105C) at 27C
Reset cause: POR
Board: MX6-SabreSD
I2C:   ready
DRAM:  2 GiB
Can't find PMIC:PFUZE100
initcall sequence 8ff970d8 failed at call 178041e0 (err=-19)
### ERROR ### Please RESET the board ###

解决问题,solution:

天嵌这块板子没有使用sabresd官方使用的PFUZE100,故要关掉相应驱动。
uboot\include\configs\Mx6q_tqcorec.h:#include "mx6sabre_common.h"
uboot\include\configs\Mx6sabre_common.h:
/* PMIC */
#define CONFIG_POWER
#define CONFIG_POWER_I2C
#define CONFIG_POWER_PFUZE100
#define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08

uboot\include\configs\mx6q_tqcorec.h 添加以下:
#undef CONFIG_POWER_PFUZE100
#undef CONFIG_LDO_BYPASS_CHECK
board/freescale/mx6q_tqcorec/mx6q_tqcorec.c 添加宏定义:
#ifdef CONFIG_POWER_PFUZE100
int power_init_board(void)
{
 //..........
}
#endif

重新编译运行,打印

U-Boot 2016.03 (Aug 28 2018 - 10:02:31 +0800)

CPU:   Freescale i.MX6Q rev1.2 996 MHz (running at 792 MHz)
CPU:   Extended Commercial temperature grade (-20C to 105C) at 33C
Reset cause: POR
Board: MX6-SabreSD
I2C:   ready
DRAM:  2 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
*** Warning - bad CRC, using default environment

No panel detected: default to Hannstar-XGA
Display: Hannstar-XGA (1024x768)
In:    serial
Out:   serial
Err:   serial
switch to partitions #0, OK
mmc0 is current device
Net:   Board Net Initialization Failed
No ethernet found.
Normal Boot
Hit any key to stop autoboot:  0 
switch to partitions #0, OK
mmc0 is current device
reading boot.scr
** Unable to read file boot.scr **
reading zImage
** Unable to read file zImage **
Booting from net ...
No ethernet found.
No ethernet found.
Bad Linux ARM zImage magic!
=> 

这里命令行提示符为"=> ",可以将之改为正式些的形式,在include/config_fallbacks.h 行79:

#ifndef CONFIG_SYS_PROMPT
#define CONFIG_SYS_PROMPT       "=> "
#endif
uboot\include\configs\mx6q_tqcorec.h 定义命令行提示符:
#define CONFIG_SYS_PROMPT		"TQCOREC > "

最后修改下board/freescale/mx6q_tqcorec/mx6q_tqcorec.c 定义Board名称:

int checkboard(void)
{
        //puts("Board: MX6-SabreSD\n");
        puts("Board: MX6Q_TQCOREC\n");
        return 0;
}

根据打印log:

Net:   Board Net Initialization Failed
No ethernet found.

问题跟踪:斜体样式

fecmxc_initialize_multi(bd, -1, CONFIG_FEC_MXC_PHYADDR,IMX_FEC_BASE);
int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
	base_mii = addr;
	bus = fec_get_miibus(base_mii, dev_id);
	phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII);//执行到phydev直接返回

以下是log文件:

U-Boot 2016.03 (Aug 28 2018 - 14:22:29 +0800)

CPU:   Freescale i.MX6Q rev1.2 996 MHz (running at 792 MHz)
CPU:   Extended Commercial temperature grade (-20C to 105C) at 33C
Reset cause: POR
Board: MX6Q_TQCOREC
I2C:   ready
DRAM:  2 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
No panel detected: default to Hannstar-XGA
Display: Hannstar-XGA (1024x768)
In:    serial
Out:   serial
Err:   serial
switch to partitions #0, OK
mmc0 is current device
Net:   ------[eth_initialize]
--------[board_eth_init]
----------[cpu_eth_init]
------------[fecmxc_initialize]
--------------[fecmxc_initialize_multi]
--------------[fecmxc_initialize_multi] bus:-1896633888
--------------[fecmxc_initialize_multi] phydev:0
Board Net Initialization Failed
No ethernet found.
Normal Boot
Hit any key to stop autoboot:  0 
TQCOREC > 

解决问题:

在include/configs/mx6sabre_common.h 修改地址:
#define CONFIG_FEC_MXC_PHYADDR          0
  1. 设置网络环境变量
setenv ethact FEC
setenv ethaddr 12:32:43:34:21:43
setenv ethprime FEC
setenv ipaddr 192.168.1.103
setenv netmask 255.255.255.0
setenv serverip 192.168.1.235
saveenv
  1. LCD

LCD屏:TN92_7LCD_V1.02
AT070TN92 F(V02)_1103.pdf

board/freescale/mx6q_tqcorec/mx6q_tqcorec.c

struct display_info_t const displays[] = {
{
	.bus	= 0,
	.addr	= 0,
	.pixfmt	= IPU_PIX_FMT_RGB24,
	.detect	= NULL,
	.enable	= enable_rgb,
	.mode	= {
		.name           = "CLAA-WVGA",
		.refresh        = 57,
		.xres           = 800,
		.yres           = 480,
		.pixclock       = 37037,
		.left_margin    = 25,
		.right_margin   = 75,
		.upper_margin   = 10,
		.lower_margin   = 10,
		.hsync_len      = 20,
		.vsync_len      = 10,
		.sync           = 0,
		.vmode          = FB_VMODE_NONINTERLACED
} }
};

在board_video_skip中获取panel环境变量 arch/arm/imx-common/video.c:18:int board_video_skip(void)

setenv panel CLAA-WVGA
saveenv

现象:屏幕上显示logo,但是也显示了一个字符串:U-boot 2016.03 (Aug 28 2018 - 15:38:16 +0800)

问题跟踪:

uboot\drivers\video\cfb_console.c
static void *video_logo(void) {
sprintf(info, " %s", version_string);
video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *) info);
}

解决问题:

#ifdef DISP_VERSION_STRING_ON_LCD
sprintf(info, " %s", version_string);
//......
video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *) info);
#endif

include/configs/mx6q_tqcorec.h :
#undef DISP_VERSION_STRING_ON_LCD

以上工作之后的log文件:

U-Boot 2016.03 (Aug 28 2018 - 16:10:34 +0800)

CPU:   Freescale i.MX6Q rev1.2 996 MHz (running at 792 MHz)
CPU:   Extended Commercial temperature grade (-20C to 105C) at 32C
Reset cause: POR
Board: MX6Q_TQCOREC
I2C:   ready
DRAM:  2 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
Display: SEIKO-WVGA (800x480)
In:    serial
Out:   serial
Err:   serial
switch to partitions #0, OK
mmc0 is current device
Net:   FEC [PRIME]
Normal Boot
Hit any key to stop autoboot:  0 
TQCOREC > 

其余记录

uboot的logo文件: tools/logos/freescale.bmp

emmc及启动情况

MMC初始化的位置: uboot\common\board_r.c

static int initr_mmc(void)
	puts("MMC:   ");
	mmc_initialize(gd->bd);			   //uboot\drivers\mmc\mmc.c						
		ret = mmc_probe(bis);
				if (board_mmc_init(bis) < 0)		//board\freescale\mx6q_tqcorec\mx6q_tqcorec.c
				cpu_mmc_init(bis);				


board_mmc_init:				
/*
 * According to the board_mmc_init() the following map is done:
 * (U-Boot device node)    (Physical Port)
 * mmc0                    SD2
 * mmc1                    SD3
 * mmc2                    eMMC
 */		
定义了mmc设备的数量: uboot\include\configs\mx6q_tqcorec.h
#define CONFIG_SYS_FSL_USDHC_NUM	3
主要是设置引脚复用,通过查看我们目标板的电路图得知,
我们的SD卡挂接在SD2_XX上,SD2_CD(GPIO_4)eMMC挂接在SD4_XX上。

static iomux_v3_cfg_t const usdhc2_pads[] 
static iomux_v3_cfg_t const usdhc3_pads[] =
static iomux_v3_cfg_t const usdhc4_pads[] =

struct fsl_esdhc_cfg usdhc_cfg[3]:
USDHC2_BASE_ADDR
USDHC3_BASE_ADDR
USDHC4_BASE_ADDR 	

根据mmc_get_boot_dev的返回值指定mmcx设备,
例如mmc_get_boot_dev返回1,则是对应mmc0
int board_mmc_get_env_dev(int devno)
{
	return devno - 1;
}	

检测哪个mmc设备在使用
int board_mmc_getcd(struct mmc *mmc)


void env_relocate_spec(void)	//uboot\common\env_mmc.c
	int dev = mmc_get_env_dev();
	mmc = find_mmc_device(dev);
	errmsg = init_mmc_for_env(mmc);
	mmc_get_env_addr(mmc, 0, &offset)
	read_env(mmc, CONFIG_ENV_SIZE, offset, buf)
	env_import(buf, 1);
	
查找mmc设备:	uboot\drivers\mmc\mmc.c
struct mmc *find_mmc_device(int dev_num)	
		list_for_each(entry, &mmc_devices) {
		m = list_entry(entry, struct mmc, link);
		if (m->block_dev.dev == dev_num)
			return m;	
	
uboot\arch\arm\cpu\armv7\mx6\soc.c
int mmc_get_env_dev(void)
{
	int devno = mmc_get_boot_dev();

	/* If not boot from sd/mmc, use default value */
	if (devno < 0)
		return CONFIG_SYS_MMC_ENV_DEV;

	return board_mmc_get_env_dev(devno);// 函数体内是return devno - 1;
}
	

uboot\arch\arm\cpu\armv7\mx6\soc.c
static int mmc_get_boot_dev(void):
	/* BOOT_CFG2[3] and BOOT_CFG2[4] */
	devno = (soc_sbmr & 0x00001800) >> 11;
	return devno;//SD2启动返回1; EMMC启动返回3
	
BOOT_CFG2[4]	BOOT_CFG2[3]  MODE
0							1						SD2_BOOT
1							1						EMMC_BOOT
0							0   					DownLoad	

uboot网卡

uboot(2016.03)网卡移植(AR8035) UBOOT支持AR8035网卡

#define CONFIG_FEC_MXC   					//mx6sabre_common.h
obj-$(CONFIG_FEC_MXC) += fec_mxc.o	        //drivers/net/Makefile
  • uboot网卡初始化整体流程
board_init_r                                     //arch/arm/lib/crt0.S																							
	initr_net			 //CONFIG_CMD_NET  		//common/board_r.c	
		eth_initialize	                        //net/eth_legacy.c																						
			board_eth_init	//board/freescale/mx6q_tqcorec/mx6q_tqcorec.c																								
				cpu_eth_init  	//CONFIG_FEC_MXC 	//arch/arm/imx-common/cpu.c	
					fecmxc_initialize  //CONFIG_FEC_MXC_PHYADDR					//drivers/net/fec_mxc.c		
						fecmxc_initialize_multi  	 //CONFIG_FEC_MXC_PHYADDR  IMX_FEC_BASE

在eth_initialize中调用eth_common_init,eth_current_changed,board_eth_init。
eth_common_init中调用miiphy_init和phy_init。
miiphy_init需要定义defined(CONFIG_MII) || defined(CONFIG_CMD_MII) ||
defined(CONFIG_PHYLIB)
phy_init需要定义CONFIG_PHYLIB,其中phy_atheros_init需要定义CONFIG_PHY_ATHEROS

  • 网卡具体初始化

miiphy_init():初始化mii_devs链表,该列表中是一系列象征mac控制器,每个miid_dev表示一条mdio总线,可挂载多个phy设备。
phy_init():根据宏定义(例如CONFIG_PHY_REALTEK、CONFIG_PHY_ATHEROS等)初始化相应一个或多个系列网卡,
其中就有我们使用的aheros(AR8035)系列网卡。
eth_current_changed():初始化关于eth的一些uboot环境变量,这里我们不需要关心。
board_eth_init():网卡的板级初始化。

  • 网卡板级具体初始化

board_eth_init()中会执行setup_iomux_enet(),setup_pcie(),cpu_eth_init()三个函数。
其中setup_iomux_enet()函数配置网卡的rgmii接口,一般不用动这部分代码。
setup_pcie()配置板子pcie总线,具体这里也不用管。
cpu_eth_init()函数会做些网卡的芯片级初始化。

  • 网卡芯片级具体初始化

cpu_eth_init()只是调用了fecmx_initialize()函数,该函数中则只调用了fecmxc_initialize_multi(bd, -1, CONFIG_FEC_MXC_PHYADDR,
IMX_FEC_BASE);函数,该函数原型为int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr);
作用是初始化挂载在器件地址为phy_id的mdio上的所有phy芯片,具体实现颇复杂但也比较有意思,有兴趣的可以自行研究下,
这里我们知道这些就已经足够了,如此看来似乎phy_id这个参数名如果改为phy_addr会更容易理解些。
到这里我们也就已经获得了移植AR8035网卡所需要的所有信息,这里做个总结:
由步骤2得知为了注册AR8035的驱动,需要定义CONFIG_PHY_REALTEK宏,为了探测到MDIO上我们的phy芯片(AR8035),需要用调用fecmxc_initialize_multi(bd,-1,CONFIG_FEC_MXC_PHYADDR,IMX_FEC_BASE),
这里CONFIG_FEC_MXC_PHYADDR就是我们的网卡芯片的器件地址,可通过电路图得知我们的地址为0,也就是说需要把CONFIG_FEC_MXC_PHYADDR宏定义为数值0。

猜你喜欢

转载自blog.csdn.net/qq_22902919/article/details/82883644