移植u-boot-2015.07-rc3之修改代码支持DM9000网卡(七)

时间:2021-10-02 10:11:44

目前的u-boot启动后有如下信息:

Net:   CS8900-0

Error: CS8900-0address not set.

板子上的是DM9000不是CS8900,网卡模块肯定是错误的嘛。看到这里,你应该有了熟悉的思路,grep "Net:" * -nR查找网卡的初始化函数,经过筛选可以断定”Net:”实在这里打印的:

common/board_r.c:581:                  puts("Net:   ");

连续跟踪可以发现如下结构:

initr_net                                                                                                                                                                                                                                                                                     

eth_initialize(net/eth.c 783)

eth_common_init

board_eth_init(board/samsung/smdk2440/smdk2440.c)

cs8900_initialize

最终发现了cs8900网卡的初始化函数cs8900_initialize,问题是找到了,但是不知道怎么修改啊!不要担心,别的开发板肯定有使用DM9000的,我们模仿其他开发板的使用方法。

搜索发现u-boot中有对DM9000支持的.c文件dm9000x.c,所以打开对应的Makefile看看dm9000x.c有没有被编译进u-boot:

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# vim drivers/net/Makefile                                                                                                                                                                

17 obj-$(CONFIG_CS8900) += cs8900.o

 18 obj-$(CONFIG_TULIP) += dc2114x.o

 19 obj-$(CONFIG_ETH_DESIGNWARE) += designware.o

 20 obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o

所以要在smdk2440.h中取消CONFIG_CS8900宏增加CONFIG_DRIVER_DM9000宏:

include/configs/smdk2440.h文件中:

46 //#define CONFIG_CS8900         /* we have a CS8900 on-board */                                                                                                                                                                    

 47 //#define CONFIG_CS8900_BASE    0x19000300

 48 //#define CONFIG_CS8900_BUS16   /* the Linux driver does accesses as shorts */

 49

 50

 51 #define CONFIG_DRIVER_DM9000

 52

make编译,出现大量错误:

drivers/net/dm9000x.c: In function 'dm9000_outblk_8bit':                                                                                                                                                                                          

drivers/net/dm9000x.c:148: error: 'DM9000_DATA' undeclared (first use in this function)

drivers/net/dm9000x.c:148: error: (Each undeclared identifier is reported only once

drivers/net/dm9000x.c:148: error: for each function it appears in.)

drivers/net/dm9000x.c: In function 'dm9000_outblk_16bit':

drivers/net/dm9000x.c:157: error: 'DM9000_DATA' undeclared (first use in this function)

可以看到这些错误都是没有定义DM9000_DATA、DM9000_IO宏造成的,也不知道这两个宏是干啥的,grep查看一下:

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# grep "DM9000_DATA" * -nR                                                                                                                                                

DM9000_DATA出现在很多头文件中,任意打开两个头文件可以看到:

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# vim include/configs/M5253DEMO.h +73                                                                                                                                

69 #define CONFIG_DRIVER_DM9000

 70 #ifdef CONFIG_DRIVER_DM9000

 71 #       define CONFIG_DM9000_BASE       (CONFIG_SYS_CS1_BASE | 0x300)

 72 #       define DM9000_IO                CONFIG_DM9000_BASE

 73 #       define DM9000_DATA              (CONFIG_DM9000_BASE + 4)

 74 #       undef CONFIG_DM9000_DEBUG

 75 #       define CONFIG_DM9000_BYTE_SWAPPED

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# vim include/configs/scb9328.h +216

213 #define CONFIG_DRIVER_DM9000            1

214 #define CONFIG_DM9000_BASE              0x16000000

215 #define DM9000_IO                       CONFIG_DM9000_BASE

216 #define DM9000_DATA                     (CONFIG_DM9000_BASE+4)

可以猜测的是我们使用DM9000至少也要定义CONFIG_DM9000_BASE、DM9000_IO和DM9000_DATA,所以在smdk2440中添加这三个宏测试编译能不能通过。

smdk2440.h中:我的环境下在smdk2440.h中使用//注释编译会出错,所以不需要的代码我就直接删除了                                                                                                        

42 /*

 43  * Hardware drivers

 44  */

 45

 46 #define CONFIG_DRIVER_DM9000

 47 #define CONFIG_DM9000_BASE                       0x16000000

 48 #define DM9000_IO                                 CONFIG_DM9000_BASE

 49 #define DM9000_DATA                              (CONFIG_DM9000_BASE+4)

 50

make编译通过。但是现在DM9000还不能使用,要移植DM9000,先来补充一下DM9000的知识:

DM9000属于内存类接口,既然是内存类接口,就需要知道访问地址是多少,位宽是多少。

所以在初始化DM9000的时候,分两步完成:

1、  设置内存控制器——时序、位宽

2、  确定访问地址

首先找到mini2440的电路图,可以看到:

移植u-boot-2015.07-rc3之修改代码支持DM9000网卡(七)

可以看到nLAN_CS接的是nGCS4.在查看2440芯片手册:


移植u-boot-2015.07-rc3之修改代码支持DM9000网卡(七)

所以基地址:CONFIG_DM9000_BASE0x2000,0000

虽然 MA9000 内部有很多寄存器,但是它提供给用户作为编程接口的就两个接口。一个是Index 端口,传输偏移地址用于确定 DM9000 内部的具体寄存器;另一个是数据端口,用于传输数据。而且两个端口使用的都是 DM9000 上的 SD[15:0]引脚,而区分何时是 Index 数据何时是传输数据呢?主要是靠 DM9000 上的 CMD 引脚来决定,当 CMD 为 0 的时候传的数据当 Index 使用,1时当传输数据使用

CMD 是接到 LADDR2 上的,所以地址为 0x20000300 时写入的是 Index 数据,为 0x20000304时写入的是传输数据。当然只要 LADDR2 为 1 就是传输数据,所以 LADDR2 为 1 的地址还可以是 0x20000305~0x20000307

所以#define DM9000_DATA             (CONFIG_DM9000_BASE + 4)

#define DM9000_IO                CONFIG_DM9000_BASE

DM9000_IO也就是写到SD[15:0]的数据当Index用的偏移

DM9000_DATA就是写到SD[15:0]的数据当数据用的偏移

以上确定访问地址就搞定了。下面需要设置内存控制器。

在lowlevel_init.S中有对整个内存控制器的初始化,因为SDRAM在没有修改的情况下都能使用,现在先不修改内存控制器的初始化值看看能不能使用,不能再回过头来修改:

所以现在先对smdk2440.h做如下修改:

smdk2440.h中:                                                                                                                                                                                                                                                                

42 /*

 43  * Hardware drivers

 44  */

 45

 46 #define CONFIG_DRIVER_DM9000

 47 #define CONFIG_DM9000_BASE              0x20000000

 48 #define DM9000_IO                                CONFIG_DM9000_BASE

 49 #define DM9000_DATA                             (CONFIG_DM9000_BASE+4)

make编译通过。

之前在board_eth_init函数中有对cs8900进行初始化的函数cs8900_initialize,现在取消CONFIG_CS9000的宏后连cs8900_initialize都不执行了。这个时候很容易想到这里应该替换成DM9000的初始化函数。而这个初始化函数当然是在dm9000x.c中,打开dm9000x.c可以看到有dm9000_initialize函数。使用grep查看dm9000_initialize的用法:

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# grep "dm9000_initialize" * -nR                                                                                                                                                

打开其中一个搜索到的文件:

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# vim board/davinci/dm355evm/dm355evm.c +77

可以看到:

74 #ifdef CONFIG_DRIVER_DM9000

 75 int board_eth_init(bd_t *bis)

 76 {

 77         return dm9000_initialize(bis);

 78 }

 79 #endif

所以模仿上面的用法可以修改board/samsung/smdk2440/smdk2440.c中的board_eth_init函数为:

board/samsung/smdk2440/smdk2440.c中:                                                                                                                                                                                                                

118 #ifdef CONFIG_CMD_NET

119 int board_eth_init(bd_t *bis)

120 {

121         int rc = 0;

122 #ifdef CONFIG_CS89dm00

123         rc = cs8900_initialize(0, CONFIG_CS8900_BASE);

124 #endif

125

126 #ifdef CONFIG_DRIVER_DM9000

127         rc = dm9000_initialize(bis);

128 #endif

129

130         return rc;

131 }

132 #endif

 

make编译下载到NorFlash并启动。可以看到:

Net:  dm9000

这就代表DM9000可能移植成功了,具体是不是真的移植成功需要使用命令验证,最简单的方法就是ping。

SMDK2410 # print        //打印环境变量情况

baudrate=115200

bootdelay=5

ethact=dm9000

ipaddr=10.0.0.110

netmask=255.255.255.0

serverip=10.0.0.1

stderr=serial

stdin=serial

stdout=serial

 

Environment size: 160/65532 bytes

 

默认情况下开发板ip为10.0.0.110,服务器ip为10.0.0.1。因为我的电脑ip为192.168.1.100,所以需要修改默认的ip:

SMDK2410 # set serverip 192.168.1.100;set ipaddr 192.168.1.200

SMDK2410 # print

baudrate=115200

bootdelay=5

ethact=dm9000

ipaddr=192.168.1.200

netmask=255.255.255.0

serverip=192.168.1.100

stderr=serial

stdin=serial

stdout=serial

 

Environment size: 168/65532 bytes

需要注意的是现在还不能使用save命令保存环境变量

 

SMDK2410 # ping 192.168.1.100

dm9000 i/o: 0x20000000, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: ff:ff:ff:ff:ff:ff

WARNING: Bad MAC address (uninitialized EEPROM?)

could not establish link

Using dm9000 device

host 192.168.1.100 is alive         //ping通电脑,说明网卡工作正常

SMDK2410 # tftp 30000000 u-boot_xt.bin

dm9000 i/o: 0x20000000, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: ff:ff:ff:ff:ff:ff

WARNING: Bad MAC address (uninitialized EEPROM?)

could not establish link

Using dm9000 device

TFTP from server 192.168.1.100; our IP address is 192.168.1.200

Filename 'u-boot_xt.bin'.

Load address: 0x30000000

Loading: ###############

         1 MiB/s

done

Bytes transferred = 217484 (3518c hex)

SMDK2410 # nand erase 0 100000;nand write 30000000 0 100000

 

NAND erase: device 0 offset 0x0, size 0x100000

Erasing at 0xe0000 -- 100% complete.

OK

 

NAND write: device 0 offset 0x0, size 0x100000                                                                                                                                                                                                                

 1048576 bytes written: OK

拨码开关拨到NandFlash启动

SMDK2410 #reset

u-boot启动正常

 

到此,DM9000网卡移植完成。

 

下一节mtdparts命令支持