目前的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的电路图,可以看到:
可以看到nLAN_CS接的是nGCS4.在查看2440芯片手册:
所以基地址:CONFIG_DM9000_BASE为0x2000,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命令支持