uboot2009,dm9000移植

(参考文档)增加DM9000网卡驱动

移植环境

  1. 主机环境:VMare下RHLE 6 ,1G内存。
  2. 编译编译环境:arm-linux-gcc v4.3.2
  3. 开发板:FL2440,4M nor flash,256M nand flash。
  4. u-boot版本:u-boot-2009.08

u-boot-2009.08版本已经对CS8900、RTL8019和DM9000X等网卡有比较完善的代码支持(代码在drivers/net/目录下),而且在S3C24XX系列中默认对CS8900网卡进行配置使用。而fl2440开发板使用的则是DM9000网卡芯片,所以只需在开发板上添加对DM9000的支持即可。还有一点,以前的 U-boot 对于网络延时部分有问题,需要修改许多地方。但是现在的U-boot 网络部分已经基本不需要怎么修改了,只有在DM9000 的驱动和NFS 的TIMEOUT 参数上需要稍微修改一下。

  1. DM9000驱动代码修改

    1. 修改static int dm9000_init函数中部分代码,如果不修改这一部分,在使用网卡的时候会报"could not establish link"的错误。

打开/drivers/net/dm9000x.c,定位到377行,修改如下:

 /* Activate DM9000 */

/* RX enable */

DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);

/* Enable TX/RX interrupt mask */

DM9000_iow(DM9000_IMR, IMR_PAR);

#if 0 //default to link MII interface

i = 0;

while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */

udelay(1000);

i++;

if (i == 1650) {

//printf("could not establish link\n");

//return 0;

break;

}

}

#endif

  1. 对于NFS,增加了延时,否则会出现"*** ERROR: Cannot mount"的错误。

打开/net/nfs.c,定位到36行,修改如下:

 

#if defined(CONFIG_CMD_NET) && defined(CONFIG_CMD_NFS)

#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */

#define NFS_RETRY_COUNT 30

#define NFS_TIMEOUT (CONFIG_SYS_HZ/1000*2000UL) //2000UL

  1. 添加网卡芯片(DM9000)的初始化函数

打开board/ fl2440/fl2440.c,定位到194行附近,文件末尾处,修改如下:

int dram_init (void)

{

gd->bd->bi_dram[0].start = PHYS_SDRAM_1;

gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;

return 0;

}

extern int dm9000_initialize(bd_t *bis);//implicit declaration of function 'dm9000_initialize'

#ifdef CONFIG_DRIVER_DM9000

int board_eth_init(bd_t *bis)

{

return dm9000_initialize(bis);

}

#endif

  1. 修改配置文件,在fl2440.h中加入相关定义

打开/include/configs/fl2440.h,定位到60行附近,修改如下:

/*

* Hardware drivers

*/

#if 0

#define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-board */

#define CS8900_BASE 0x19000300

#define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */

#endif

#define CONFIG_NET_MULTI 1

#define CONFIG_DRIVER_DM9000 1

#define CONFIG_DM9000_BASE 0x20000300 //网卡片选地址

#define DM9000_IO CONFIG_DM9000_BASE

#define DM9000_DATA (CONFIG_DM9000_BASE+4) //网卡数据地址

#define CONFIG_DM9000_NO_SROM 1

//#define CONFIG_DM9000_USE_16BIT

#undef CONFIG_DM9000_DEBUG

注意:

u-boot-2009.08 可以自动检测DM9000网卡的位数,根据开发板原理图可知网卡的数据位为16位,并且网卡位于CPU的BANK4上,所以只需在 board/fl2440/lowlevel_init.S中设置 #define B4_BWSCON (DW16) 即可,不需要此处的

#define CONFIG_DM9000_USE_16BIT 1

给u-boot加上ping命令,用来测试网络通不通

/*

* Command line configuration.

*/

#include <config_cmd_default.h>

#define CONFIG_CMD_CACHE

#define CONFIG_CMD_DATE

#define CONFIG_CMD_ELF

#define CONFIG_CMD_NAND

#define CONFIG_CMD_JFFS2 /* JFFS2 Support*/

#define CONFIG_CMD_PING /*ping command support*/

恢复被注释掉的网卡MAC地址和修改你合适的开发板IP地址以及内核启动参数:

#define CONFIG_BOOTDELAY 3

#define CONFIG_ETHADDR 08:00:3e:26:0a:5b

#define CONFIG_NETMASK 255.255.255.0

#define CONFIG_IPADDR 192.168.1.15

#define CONFIG_SERVERIP 192.168.1.124

#define CONFIG_GATEWAYIP 192.168.1.1

#define CONFIG_OVERWRITE_ETHADDR_ONCE

/*#define CONFIG_BOOTFILE "elinos-lart" */

  1. 重新编译u-boot,下载到Nand中从Nand启动,查看启动信息和环境变量并使用ping命令测试网卡,操作如下:

ping测试:
[u-boot@FL2440]# ping 192.168.1.124
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:00:00:00:00:00
operating at 100M full duplex mode
ping failed; host 192.168.1.124 is not alive

现在有个问题就是ping不能通过。出现问题的地方可能是DM9000网卡驱动中关闭网卡的地方,如是就试着修改代码如下:

打开drivers/net/dm9000x.c ,定位到456行附近,屏蔽掉dm9000_halt函数中的内容:

/*

Stop the interface.

The interface is stopped when it is brought.

*/

static void dm9000_halt(struct eth_device *netdev)

{

#if 0

DM9000_DBG("%s\n", __func__);

/* RESET devie */

phy_write(0, 0x8000); /* PHY RESET */

DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */

DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */

DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */

#endif

}

重新编译下载,nand启动,运行结果:

[u-boot@FL2440]# ping 192.168.1.124
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:00:00:00:00:00
operating at unknown: 0 mode
ping failed; host 192.168.1.124 is not alive

[u-boot@FL2440]# setenv gatewayip 192.168.1.1
[u-boot@FL2440]# setenv ethaddr 12:34:56:78:9a:bc //MAC地址,随便设
[u-boot@FL2440]# ping 192.168.1.124
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at unknown: 0 mode
Using dm9000 device
host 192.168.1.124 is alive


[u-boot@FL2440]# saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x4000000000002 --   0% complete.
Writing to Nand... done

[u-boot@FL2440]# ping 192.168.1.124
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at unknown: 0 mode
Using dm9000 device
host 192.168.1.124 is alive
[u-boot@FL2440]#

结果,只是第一次ping不通,以后都是可以ping通的(据网友们说这是正常的。

  1. tftp功能测试

首先需要将fl2440的内核文件uImage_362复制到linux 宿主机的/home/tftpboot目录下,然后执行:

[u-boot@FL2440]# tftp 0x30008000 uImage_362
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at unknown: 0 mode
Using dm9000 device
TFTP from server 192.168.1.124; our IP address is 10.1.0.129
Filename 'uImage_362'.
Load address: 0x30008000
Loading: T ################################################T #################
         #############T T ######################T
done
Bytes transferred = 2022348 (1edbcc hex)
[u-boot@FL2440]#

至此DM9000网卡驱动移植成功。但是还发现一个问题:"这里之前还是"operating at 100M full duplex mode",而现在怎么是"operating at unknown: 0 mode"?原来是dm9000的phy_read(int reg)函数延时出了问题,现操作如下:

打开/drivers/net/dm9000x.c,定位到595行附近,修改如下:

/*

Read a word from phyxcer

*/

static u16

phy_read(int reg)

{

u16 val;

/* Fill the phyxcer register into REG_0C */

DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);

DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */

udelay(1000); //udelay(100); /* Wait read complete */

DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */

val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);

/* The read data keeps on REG_0D & REG_0E */

DM9000_DBG("phy_read(0x%x): 0x%x\n", reg, val);

return val;

}

重新编译下载后:

[u-boot@FL2440]# ping 192.168.1.124
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at unknown: 15 mode
Using dm9000 device
ping failed; host 192.168.1.124 is not alive

[u-boot@FL2440]# ping 192.168.1.124
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at 100M full duplex mode
Using dm9000 device
host 192.168.1.124 is alive
[u-boot@FL2440]#
可以看到"operating at 100M full duplex mode"这样的信息了

上面还有一个问题,就是问什么第一次ping不通呢?经过尝试,操作如下:

打开/drivers/net/dm9000x.c,定位到377行,修改如下:

/* Activate DM9000 */

/* RX enable */

DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);

/* Enable TX/RX interrupt mask */

DM9000_iow(DM9000_IMR, IMR_PAR);

#if 1 //internet delay loop

i = 0;

while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */

udelay(1000);

i++;

if (i == 3000) {

printf("could not establish link\n");

return 0;

//break;

}

}

#endif

修改后重新编译下载:

[u-boot@FL2440]# ping 192.168.1.124
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at 100M full duplex mode
Using dm9000 device
host 192.168.1.124 is alive
[u-boot@FL2440]#

OK! 第一次ping不通的问题解决了!

posted on 2012-11-23 13:49  WithYouTh  阅读(717)  评论(0编辑  收藏  举报