本移植过程假设用户用户是从给定的 demo 板开发自己的新产品。
你也可以参考: http://wenku.baidu.com/view/723e304be45c3b3567ec8b56.html 这篇文章
假设用的 demo 板是 omap3devkit8000,我们自己的板叫 myboard.
看这篇文章前可以先看我写的前一篇文章: u-boot 的移植,然后再做如下的操作
目标是: demo 板中的 u-boot 是用的 DM9000 网卡,自己硬件用的 smc911x 网卡
大的方案是先找到支持 smc911x 网卡的 uboot(高版本的 uboot 支持), 然后跟自己 demo 板的 uboot 对比。
1> 拷贝下面两个驱动文件
/drivers/net/smc911x.c
/drivers/net/smc911x.h
2> 在 myboard.h 增加以下宏定义
/*
* Net chip
*/
#define CONFIG_SMC911X
#define CONFIG_SMC911X_16_BIT
#define CONFIG_SMC911X_BASE 0x2C000000 /* 网卡的基地址 */
3> /board/myboard/myboard.c 文件中加入以下两个函数(参考其它 uboot 做的)
/*
* Routine: setup_net_chip
* Description: Setting up the configuration GPMC registers specific to the
* Ethernet hardware.
*/
static void setup_net_chip(void)
{
/* 初始化第一个网卡 */
__raw_writel(0x00001000, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG1);
__raw_writel(0x001e1e00, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG2);
__raw_writel(0x00080300, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG3);
__raw_writel(0x1c091c09, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG4);
__raw_writel(0x04181f1f, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG5);
__raw_writel(0x00000FcF, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG6);
__raw_writel(0x00000f68, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG7);
/* 初始化第二个网卡 */
__raw_writel(0x00001000, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG1);
__raw_writel(0x001e1e00, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG2);
__raw_writel(0x00080300, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG3);
__raw_writel(0x1c091c09, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG4);
__raw_writel(0x04181f1f, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG5);
__raw_writel(0x00000FcF, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG6);
__raw_writel(0x00000f6c, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG7);
/* configure gpio137 as output pin */
writel(readl(0x49056034) & ~(0x1 << 9), 0x49056034);
writel(0x1 << 9, 0x49056090);
/* configure gpio138 as output pin , set output 0 */
writel(readl(0x49056034) & ~(0x1 << 10), 0x49056034);
writel(0x1 << 10, 0x49056090);
}
int board_eth_init(bd_t *bis) /* 该函数在 net/eth.c 中会被调用 */
{
int rc = 0;
#ifdef CONFIG_SMC911X
rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
#endif
return rc;
}
4> 在 myboard.c 的 misc_init_r( ) 函数中,加入如下代码
#if defined(CONFIG_CMD_NET)
setup_net_chip();
#endif
5> 在 board/myboard/mem.c 文件中修改 gpmc_init(void) 的网卡相关部分
备注:从这一步看,前面的 setup_net_chip(void) 应该是多余的
原来为:
#ifdef CONFIG_DRIVER_DM9000
__raw_writel(0x00001000, GPMC_CONFIG_CS0 + (6 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG1);
__raw_writel(0x001e1e00, GPMC_CONFIG_CS0 + (6 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG2);
__raw_writel(0x00080300, GPMC_CONFIG_CS0 + (6 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG3);
__raw_writel(0x1c091c09, GPMC_CONFIG_CS0 + (6 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG4);
__raw_writel(0x04181f1f, GPMC_CONFIG_CS0 + (6 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG5);
__raw_writel(0x00000FcF, GPMC_CONFIG_CS0 + (6 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG6);
__raw_writel(0x00000f6c, GPMC_CONFIG_CS0 + (6 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG7);
#endif
修改为:
#ifdef CONFIG_SMC911X
/* 第一个网卡,从硬件原理图上可以看出,片选用的 GPMC_CS4 */
__raw_writel(0x00001000, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG1);
__raw_writel(0x001e1e01, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG2);
__raw_writel(0x00080300, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG3);
__raw_writel(0x1c091c09, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG4);
__raw_writel(0x04181f1f, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG5);
__raw_writel(0x00000FcF, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG6);
__raw_writel(0x00000f68, GPMC_CONFIG_CS0 + (4 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG7);
/* 第二个网卡,从硬件原理图上可以看出,片选用的 GPMC_CS5 */
__raw_writel(0x00001000, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG1);
__raw_writel(0x001e1e01, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG2);
__raw_writel(0x00080300, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG3);
__raw_writel(0x1c091c09, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG4);
__raw_writel(0x04181f1f, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG5);
__raw_writel(0x00000FcF, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG6);
__raw_writel(0x00000f6c, GPMC_CONFIG_CS0 + (5 * GPMC_CONFIG_WIDTH) + GPMC_CONFIG7);
#endif
6> /net/eth.c 文件前面加入如下代码
/*
* CPU and board-specific Ethernet initializations. Aliased function
* signals caller to move on
*/
static int __def_eth_init(bd_t *bis)
{
return -1;
}
int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
然后修改下面函数:
int eth_initialize(bd_t *bis)
{
char enetvar[32];
unsigned char env_enetaddr[6];
int i, eth_number = 0;
char *tmp, *end;
eth_devices = NULL;
eth_current = NULL;
show_boot_progress (64);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_init();
#endif
/* 下面为新增的代码 */
/* Try board-specific initialization first. If it fails or isn't
* present, try the cpu-specific initialization */
if (board_eth_init(bis) < 0)
cpu_eth_init(bis);
............
}