u-boot移植之mmc,网卡配置
2016-02-02 15:42
429 查看
最近做的一个产品是用的mx6系列cpu,包括6q、6d、6s、6ul,有已经移植好的成品6q的u-boot,但是只兼容6d,并不兼容6s,所以需要为6s量身打造一个u-boot。
首先,需要下载u-boot:
笔者尝试过Yocto,LTIB,以及手动打补丁的方式全部以失败告终,还顺手写了一篇Yocto的安装说明。
最后笔者是通过fresscale的git下载的最新的u-boot源码,竟然不用修改就能起了,而且mx6dl和mx6s是兼容的,不得不说fresscale的git还是靠谱啊!!
这里会给出所用的u-boot源码的下载方法:
配置及编译:
#make mx6solosabreauto_defconfig
#make
这里采用的是mx6solosabreauto_defconfig配置u-boot,根据顶层Makefile,以及配置文件内容可以知道其实这个配置文件用的还是mx6qsabreauto.c和mx6qsabreauto.h。所以后文修改的便是这两个文件。
烧写u-boot到sd卡:
#dd if=u-boot.imx of=/dev/sdb bs=512 seek=2 conv=fsync
下载的源码编译后直接烧写到sd卡,能够启动,但是mmc和net设备识别出错,这也是这篇文章重点要讲的地方。
MMC:
先是有关于mmc的内容。根据原理图可以知道一共采用了一块emmc,加上sd卡,便是两个mmc设备。
笔者所用的板子支持最多3块mmc设备,本文中只用到了两个,uSDHC1为SD卡,uSDHC2没有被使用,uSDHC3是板子上的emmc。
根据原理图,寻找mmc设备的检测管脚:
在原理图中寻找SDx_CDn的管脚,其中x代表1.2.3。最后之发现了一个SD1_CDn,再找到引出的GPIO口,笔者的SD卡检测口为GPIO1_IO0,emmc并没有检测管脚。
了解了管脚的使用之后开始配置管脚。
mx6qsabreauto.c
#define USDHC1_CD_GPIO IMX_GPIO_NR(1, 0)
//#define USDHC3_CD_GPIO IMX_GPIO_NR(6, 15)
找到这两行,第一行改为(1,0),第二行并没有用到,直接注释掉。
由于emmc没有检测管脚,所以需要更改检测检测管脚的函数使emmc能顺利被初始化(有点拗口):
int board_mmc_getcd(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
int ret = 0;
switch (cfg->esdhc_base) {
case USDHC1_BASE_ADDR:
gpio_direction_input(USDHC1_CD_GPIO);
ret = !gpio_get_value(USDHC1_CD_GPIO);
break;
case USDHC3_BASE_ADDR:
// gpio_direction_input(USDHC3_CD_GPIO);
// ret = !gpio_get_value(USDHC3_CD_GPIO);
ret = 1 ;
break;
}
return ret;
}
注释掉原来的两行代码,直接将ret赋值为1,表示强制认为该设备已经存在。
到此处时再编译下载已经能够识别mmc设备了,u-boot下mmc dev [port]切换设备,mmcinfo查看设备信息。
NET:
接下来就是网卡的配置,先看好网卡的型号,笔者所用的是ATHEROS8031的网卡,根据原理图知道默认是RGMII模式。
mx6qsabreauto.h
#define CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_CMD_NET
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_PHYLIB
#define CONFIG_PHY_ATHEROS
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_XCV_TYPE RGMII
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_FEC_MXC_PHYADDR 1
#define CONFIG_ETHADDR CONFIG_ENET_ETHADDR
#define CONFIG_NETMASK CONFIG_ENET_NETMASK
#define CONFIG_IPADDR CONFIG_ENET_IPADDR
#define CONFIG_SERVERIP CONFIG_ENET_SERVERIP
#define CONFIG_GATEWAYIP CONFIG_EMMC_GATEWAYIP
上述代码是对网卡型号,模式的定义,原来的mx6qsabreauto.h文件是没有网卡的宏定义的,这里需要都补上。
由于板子是自动从网络加载boot的,所以还需要配置网关等。
mx6qsabreauto.h
#define CONFIG_ENET_ETHADDR 12:34:56:78:9A:BC
#define CONFIG_ENET_IPADDR 192.168.1.180
#define CONFIG_ENET_SERVERIP 192.168.1.178
#define CONFIG_EMMC_GATEWAYIP 192.168.1.1
#define CONFIG_ENET_NETMASK 255.255.255.0
#define CONFIG_ARP_TIMEOUT 200UL
到这里,头文件的添加已经完成。
mx6qsabreauto.c
static iomux_v3_cfg_t const enet_pads[] = {
MX6_PAD_KEY_COL1__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_KEY_COL2__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_GPIO_16__ENET_REF_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
};
这是没改之前的管脚配置,需要根据原理图更改:
mx6qsabreauto.c
static iomux_v3_cfg_t const enet_pads[] = {
/* Tx */
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* Rx */
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* Phy */
MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* Ref clock*/
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
};
重点是MDIO和MDC两个管脚的配置,其他都没变。
改完管脚配置之后,网卡也能够识别了。到此,大功告成!
首先,需要下载u-boot:
笔者尝试过Yocto,LTIB,以及手动打补丁的方式全部以失败告终,还顺手写了一篇Yocto的安装说明。
最后笔者是通过fresscale的git下载的最新的u-boot源码,竟然不用修改就能起了,而且mx6dl和mx6s是兼容的,不得不说fresscale的git还是靠谱啊!!
这里会给出所用的u-boot源码的下载方法:
#git clone http://git.freescale.com/git/cgit.cgi/imx/uboot-imx.git -b imx_v2015.04_3.14.52_1.1.0_ga
配置及编译:
#make mx6solosabreauto_defconfig
#make
这里采用的是mx6solosabreauto_defconfig配置u-boot,根据顶层Makefile,以及配置文件内容可以知道其实这个配置文件用的还是mx6qsabreauto.c和mx6qsabreauto.h。所以后文修改的便是这两个文件。
烧写u-boot到sd卡:
#dd if=u-boot.imx of=/dev/sdb bs=512 seek=2 conv=fsync
下载的源码编译后直接烧写到sd卡,能够启动,但是mmc和net设备识别出错,这也是这篇文章重点要讲的地方。
MMC:
先是有关于mmc的内容。根据原理图可以知道一共采用了一块emmc,加上sd卡,便是两个mmc设备。
笔者所用的板子支持最多3块mmc设备,本文中只用到了两个,uSDHC1为SD卡,uSDHC2没有被使用,uSDHC3是板子上的emmc。
根据原理图,寻找mmc设备的检测管脚:
在原理图中寻找SDx_CDn的管脚,其中x代表1.2.3。最后之发现了一个SD1_CDn,再找到引出的GPIO口,笔者的SD卡检测口为GPIO1_IO0,emmc并没有检测管脚。
了解了管脚的使用之后开始配置管脚。
mx6qsabreauto.c
#define USDHC1_CD_GPIO IMX_GPIO_NR(1, 0)
//#define USDHC3_CD_GPIO IMX_GPIO_NR(6, 15)
找到这两行,第一行改为(1,0),第二行并没有用到,直接注释掉。
由于emmc没有检测管脚,所以需要更改检测检测管脚的函数使emmc能顺利被初始化(有点拗口):
int board_mmc_getcd(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
int ret = 0;
switch (cfg->esdhc_base) {
case USDHC1_BASE_ADDR:
gpio_direction_input(USDHC1_CD_GPIO);
ret = !gpio_get_value(USDHC1_CD_GPIO);
break;
case USDHC3_BASE_ADDR:
// gpio_direction_input(USDHC3_CD_GPIO);
// ret = !gpio_get_value(USDHC3_CD_GPIO);
ret = 1 ;
break;
}
return ret;
}
注释掉原来的两行代码,直接将ret赋值为1,表示强制认为该设备已经存在。
到此处时再编译下载已经能够识别mmc设备了,u-boot下mmc dev [port]切换设备,mmcinfo查看设备信息。
NET:
接下来就是网卡的配置,先看好网卡的型号,笔者所用的是ATHEROS8031的网卡,根据原理图知道默认是RGMII模式。
mx6qsabreauto.h
#define CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_CMD_NET
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_PHYLIB
#define CONFIG_PHY_ATHEROS
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_XCV_TYPE RGMII
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_FEC_MXC_PHYADDR 1
#define CONFIG_ETHADDR CONFIG_ENET_ETHADDR
#define CONFIG_NETMASK CONFIG_ENET_NETMASK
#define CONFIG_IPADDR CONFIG_ENET_IPADDR
#define CONFIG_SERVERIP CONFIG_ENET_SERVERIP
#define CONFIG_GATEWAYIP CONFIG_EMMC_GATEWAYIP
上述代码是对网卡型号,模式的定义,原来的mx6qsabreauto.h文件是没有网卡的宏定义的,这里需要都补上。
由于板子是自动从网络加载boot的,所以还需要配置网关等。
mx6qsabreauto.h
#define CONFIG_ENET_ETHADDR 12:34:56:78:9A:BC
#define CONFIG_ENET_IPADDR 192.168.1.180
#define CONFIG_ENET_SERVERIP 192.168.1.178
#define CONFIG_EMMC_GATEWAYIP 192.168.1.1
#define CONFIG_ENET_NETMASK 255.255.255.0
#define CONFIG_ARP_TIMEOUT 200UL
到这里,头文件的添加已经完成。
mx6qsabreauto.c
static iomux_v3_cfg_t const enet_pads[] = {
MX6_PAD_KEY_COL1__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_KEY_COL2__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_GPIO_16__ENET_REF_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
};
这是没改之前的管脚配置,需要根据原理图更改:
mx6qsabreauto.c
static iomux_v3_cfg_t const enet_pads[] = {
/* Tx */
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* Rx */
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* Phy */
MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* Ref clock*/
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
};
重点是MDIO和MDC两个管脚的配置,其他都没变。
改完管脚配置之后,网卡也能够识别了。到此,大功告成!
相关文章推荐
- U-Boot源码分析及移植-fs2410
- U-BOOT源码分析及移植
- U-Boot启动过程--详细版的完全分析(二)
- U-Boot-2009-03移植笔记(移植准备)
- U-Boot-2009-03移植笔记(点亮第一展灯)
- U_boot 的 bootcmd 和bootargs参数详解
- U-Boot移植全程指导
- u-boot1.1.6-undefined reference to "raise"
- lin 学习笔记之SCI
- 09课01节 u-boot-1.1.16编译补丁;
- u-boot模仿
- 自定义u-boot启动logo的方法
- 2440 u-boot编译
- u-boot.lds与-Ttext $(TEXT_BASE)
- A20网络机顶盒移植4.5内核+U-Boot+rootfs
- U-Boot移植(1)--在U-boot中建立自己的开发板
- 追踪uboot下tftp命令的代码执行过程-Nagul
- 嵌入式系统 Boot Loader 技术内幕
- 嵌入式linux系统log文件的几个地方
- 常用的uboot的bootargs设置