主题 : uboot1.1.6——DM9000移植问题,求点击 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 74119
精华: 0
发帖: 13
金钱: 65 两
威望: 13 点
贡献值: 0 点
综合积分: 26 分
注册时间: 2012-07-19
最后登录: 2017-09-13
楼主  发表于: 2012-12-17 09:20

 uboot1.1.6——DM9000移植问题,求点击

帖子有些屁长,希望大家能耐心看完~~
最近在学习uboot,所以选用了较低版本的u-boot-1.1.6,移植到mini2440,现在在dm9000网卡驱动这卡住了。
过程是这样的:
1、在board/mini2440/mini24440.h中添加dm9000的需要的一些宏定义
复制代码
  1. #if 0
  2. #define CONFIG_DRIVER_CS8900    1    /* we have a CS8900 on-board */
  3. #define CS8900_BASE        0x19000300
  4. #define CS8900_BUS16        1 /* the Linux driver does accesses as shorts */
  5. #endif
  6. #define CONFIG_DRIVER_DM9000        1
  7. #define CONFIG_NET_MULTI            1
  8. #define CONFIG_DM9000_NO_SROM       1
  9. #define CONFIG_DM9000_BASE        0x20000300   //网卡片选地址
  10. #define DM9000_IO            CONFIG_DM9000_BASE  
  11. #define DM9000_DATA            (CONFIG_DM9000_BASE + 4) //网卡数据地址
  12. #define CONFIG_BOOTDELAY    3
  13. /*#define CONFIG_BOOTARGS        "root=ramfs devfs=mount console=ttySA0,9600" */
  14. #define CONFIG_ETHADDR            08:00:3e:26:0a:5b
  15. #define CONFIG_NETMASK          255.255.255.0
  16. #define CONFIG_IPADDR        172.31.108.211//开发板IP地址
  17. #define CONFIG_SERVERIP        172.31.108.66//Linux主机IP地址


2、net/eth.c中的eth_initialize函数中添加
复制代码
  1. #ifdef CONFIG_DRIVER_DM9000
  2.     dm9000_initialize(bis);
  3. #endif



3、drivers/dm9000x.c中添加参照高版本的写法添加dm9000_get_enetaddr和dm9000_initialize函数
复制代码
  1. static void dm9000_get_enetaddr(struct eth_device *dev)
  2. {
  3. #if !defined(CONFIG_DM9000_NO_SROM)
  4.     int i;
  5.     for (i = 0; i < 3; i++)
  6.         phy_read(i, dev->enetaddr + (2 * i));
  7. #endif
  8. }
  9. int dm9000_initialize(bd_t *bis)
  10. {
  11.     struct eth_device *dev = &(dmfe_info.netdev);
  12.     // Load MAC address from EEPROM
  13.     dm9000_get_enetaddr(dev);
  14.     dev->init = eth_init;
  15.     dev->halt = eth_halt;
  16.     dev->send = eth_send;
  17.     dev->recv = eth_rx;
  18.     sprintf(dev->name, "dm9000");
  19.     eth_register(dev);
  20.     return 0;
  21. }


上面用到的结构体dmfe_info中需要先添加成员
复制代码
  1. /* Structure/enum declaration ------------------------------- */
  2. typedef struct board_info {
  3.     u32 runt_length_counter;    /* counter: RX length < 64byte */
  4.     u32 long_length_counter;    /* counter: RX length > 1514byte */
  5.     u32 reset_counter;    /* counter: RESET */
  6.     u32 reset_tx_timeout;    /* RESET caused by TX Timeout */
  7.     u32 reset_rx_status;    /* RESET caused by RX Statsus wrong */
  8.     u16 tx_pkt_cnt;
  9.     u16 queue_start_addr;
  10.     u16 dbug_cnt;
  11.     u8 phy_addr;
  12.     u8 device_wait_reset;    /* device state */
  13.     u8 nic_type;        /* NIC type */
  14.     unsigned char srom[128];
  15.         <span style="color: #FF0000;">struct eth_device netdev;</span>
  16. } board_info_t;
  17. board_info_t dmfe_info;


4、drivers/dm9000x.c中的eth_init函数进行修改
复制代码
  1. ..
  2. /* Set Node address */
  3. #ifndef CONFIG_AT91SAM9261EK
  4.     for (i = 0; i < 6; i++)
  5.         ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
  6. #endif
  7.     if (is_zero_ether_addr(bd->bi_enetaddr) ||
  8.         is_multicast_ether_addr(bd->bi_enetaddr)) {
  9.         /* try reading from environment */
  10.         u8 i;
  11.         char *s, *e;
  12.         s = getenv ("ethaddr");
  13.         for (i = 0; i < 6; ++i) {
  14.             bd->bi_enetaddr[i] = s ?
  15.                 simple_strtoul (s, &e, 16) : 0;
  16.             if (s)
  17.                 s = (*e) ? e + 1 : e;
  18.         }
  19.     }
  20. ...
  21. ...
  22. #if 0  //屏蔽掉dm9000_init函数中的这一部分,不然使用网卡的时候会报“could not establish link”的错误
  23.     i = 0;
  24.     while (!(phy_read(1) & 0x20)) {    /* autonegation complete bit */
  25.         udelay(1000);
  26.         i++;
  27.         if (i == 10000) {
  28.             printf("could not establish link\n");
  29.             return 0;
  30.         }
  31.     }
  32.     /* see what we've got */
  33.     lnk = phy_read(17) >> 12;
  34.     printf("operating at ");
  35.     switch (lnk) {
  36.     case 1:
  37.         printf("10M half duplex ");
  38.         break;
  39.     case 2:
  40.         printf("10M full duplex ");
  41.         break;
  42.     case 4:
  43.         printf("100M half duplex ");
  44.         break;
  45.     case 8:
  46.         printf("100M full duplex ");
  47.         break;
  48.     default:
  49.         printf("unknown: %d ", lnk);
  50.         break;
  51.     }
  52.     printf("mode\n");
  53. #endif
  54. ...
  55. ...


我就做了就这些,编译uboot后,问题出来了:
1、报错eth_init;eth_halt;eth_send;eth_rx;这四个函数重复定义
我看了一下,确实eth.c和dm9000x.c下都有这四个函数,高版本的uboot已经把dm9000.c中的这四个函数改为dm9000_init;dm9000_halt;dm9000_send;dm9000_rx;所以也就改了这四个函数和用到他们的地方,编译没有错误了
但是之前没有修改dm9000的那些地方之前编译却不会报错,这是为什么呢?不重复吗?我也没有发现对这四个函数有什么条件编译、、求大家解释解释!

2 下载编译生成的bin后,串口显示
...
in:    serial
out:   serial
error: serial
net:   dm9000
没有错误,但是printenv后显示的ipaddr和serveraddr等网卡信息都是之前默认的,10.0.0.110、10.0.0.1,根本没有显示我修改的。
我查了一下源码,在smdk2410.h中定义了这一ip值,我就不明白了,为什么会用到它?

3、board.c中先执行
/* initialize environment */
env_relocate ();
然后再调用eth_initialize,我跟踪代码发现有一个结构体default_environment经常被用到
复制代码
  1. static uchar default_environment[] = {
  2. #if defined(CONFIG_BOOTARGS)
  3.     "bootargs=" CONFIG_BOOTARGS "\0"
  4. #endif
  5. #if defined(CONFIG_BOOTCOMMAND)
  6.     "bootcmd=" CONFIG_BOOTCOMMAND "\0"
  7. #endif
  8. #if defined(CONFIG_RAMBOOTCOMMAND)
  9.     "ramboot=" CONFIG_RAMBOOTCOMMAND "\0"
  10. #endif
  11. #if defined(CONFIG_NFSBOOTCOMMAND)
  12.     "nfsboot=" CONFIG_NFSBOOTCOMMAND "\0"
  13. #endif
  14. #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
  15.     "bootdelay=" MK_STR (CONFIG_BOOTDELAY) "\0"
  16. #endif
  17. #if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
  18.     "baudrate=" MK_STR (CONFIG_BAUDRATE) "\0"
  19. #endif
  20. #ifdef    CONFIG_LOADS_ECHO
  21.     "loads_echo=" MK_STR (CONFIG_LOADS_ECHO) "\0"
  22. #endif
  23. #ifdef    CONFIG_ETHADDR
  24.     "ethaddr=" MK_STR (CONFIG_ETHADDR) "\0"
  25. #endif
  26. #ifdef    CONFIG_ETH1ADDR
  27.     "eth1addr=" MK_STR (CONFIG_ETH1ADDR) "\0"
  28. #endif
  29. #ifdef    CONFIG_ETH2ADDR
  30.     "eth2addr=" MK_STR (CONFIG_ETH2ADDR) "\0"
  31. #endif
  32. #ifdef    CONFIG_ETH3ADDR
  33.     "eth3addr=" MK_STR (CONFIG_ETH3ADDR) "\0"
  34. #endif
  35. #ifdef    CONFIG_ETHPRIME
  36.     "ethprime=" CONFIG_ETHPRIME "\0"
  37. #endif
  38. #ifdef    CONFIG_IPADDR
  39.     "ipaddr=" MK_STR (CONFIG_IPADDR) "\0"
  40. #endif
  41. #ifdef    CONFIG_SERVERIP
  42.     "serverip=" MK_STR (CONFIG_SERVERIP) "\0"
  43. #endif
  44. #ifdef    CFG_AUTOLOAD
  45.     "autoload=" CFG_AUTOLOAD "\0"
  46. #endif
  47. #ifdef    CONFIG_ROOTPATH
  48.     "rootpath=" MK_STR (CONFIG_ROOTPATH) "\0"
  49. #endif
  50. #ifdef    CONFIG_GATEWAYIP
  51.     "gatewayip=" MK_STR (CONFIG_GATEWAYIP) "\0"
  52. #endif
  53. #ifdef    CONFIG_NETMASK
  54.     "netmask=" MK_STR (CONFIG_NETMASK) "\0"
  55. #endif
  56. #ifdef    CONFIG_HOSTNAME
  57.     "hostname=" MK_STR (CONFIG_HOSTNAME) "\0"
  58. #endif
  59. #ifdef    CONFIG_BOOTFILE
  60.     "bootfile=" MK_STR (CONFIG_BOOTFILE) "\0"
  61. #endif
  62. #ifdef    CONFIG_LOADADDR
  63.     "loadaddr=" MK_STR (CONFIG_LOADADDR) "\0"
  64. #endif
  65. #ifdef    CONFIG_PREBOOT
  66.     "preboot=" CONFIG_PREBOOT "\0"
  67. #endif
  68. #ifdef    CONFIG_CLOCKS_IN_MHZ
  69.     "clocks_in_mhz=" "1" "\0"
  70. #endif
  71. #if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
  72.     "pcidelay=" MK_STR (CONFIG_PCI_BOOTDELAY) "\0"
  73. #endif
  74. #ifdef  CONFIG_EXTRA_ENV_SETTINGS
  75.     CONFIG_EXTRA_ENV_SETTINGS
  76. #endif
  77.     "\0"            /* Termimate env_t data with 2 NULs */
  78. };


问题是,这里的CONFIG_XXX  在很多.h(include/config/xxx.h)都定义到了,怎么才能确定他们用到的是哪个.h文件的值呢,问题2是不是因为这里的结构体值错误而出现的呢?

问题可能比较小白,没办法,才学uboot的,两天了,是在理不出头绪,都郁闷出翔了~~所以在这里发帖向大家求助,希望大家给与些帮助和建议,不管哪方面的,再次表示感谢!
另外贴出uboot1.1.6的下载地址:ftp://ftp.denx.de/pub/u-boot/u-boot-1.1.6.tar.bz2
[ 此帖被racwin在2012-12-17 09:37重新编辑 ]
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2012-12-17 12:22
1、报错eth_init;eth_halt;eth_send;eth_rx;这四个函数重复定义
我看了一下,确实eth.c和dm9000x.c下都有这四个函数,高版本的uboot已经把dm9000.c中的这四个函数改为dm9000_init;dm9000_halt;dm9000_send;dm9000_rx;所以也就改了这四个函数和用到他们的地方,编译没有错误了
但是之前没有修改dm9000的那些地方之前编译却不会报错,这是为什么呢?不重复吗?我也没有发现对这四个函数有什么条件编译、、求大家解释解释!

在原始1.1.6版本的u-boot里,drivers/dm9000x.c由CONFIG_DRIVER_DM9000条件编译。另外,net/eth.c由CFG_CMD_NET和CONFIG_NET_MULTI条件编译


2 下载编译生成的bin后,串口显示
...
in:    serial
out:   serial
error: serial
net:   dm9000
没有错误,但是printenv后显示的ipaddr和serveraddr等网卡信息都是之前默认的,10.0.0.110、10.0.0.1,根本没有显示我修改的。
我查了一下源码,在smdk2410.h中定义了这一ip值,我就不明白了,为什么会用到它?

这可能是由

在board/mini2440/mini24440.h中添加dm9000的需要的一些宏定义

造成的,你需要把这些定义加入到mini2440对应的配置头文件里,这个文件应该在include/configs/目录下面。


问题是,这里的CONFIG_XXX  在很多.h(include/config/xxx.h)都定义到了,怎么才能确定他们用到的是哪个.h文件的值呢,问题2是不是因为这里的结构体值错误而出现的呢?

很可能是这样的。你可以通过查看include/config.h确定当前用的配置头文件。这个文件里会包含类似下面的一行
复制代码
  1. #include <configs/XXXX.h>

另外,这个配置应该是在你编译是通过make XXXX_config决定的。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
2楼  发表于: 2012-12-17 17:30
下载到开发板后,网络接口的提示灯也没有亮,应该是网卡初始化没有成功;

网卡初始化要在通过eth_init()调用dm9000_init()时才会执行。你可以打开dm9000x.c里CONFIG_DM9000_DEBUG来追踪dm9000的初始化流程。

但是既然没有成功,那print之后显示的10.0.0.110、10.0.0.1,等信息是怎么来的

print显示的是环境变量里的设置,和网卡是否初始化没有关系

环境变量的初始值为什么不是用的include/configs/mini2440.h里面的

这我就不知道了,代码里有别的地方设置了这些环境变量?
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."