移植u-boot-2015.07-rc3之修改代码支持DM9000网卡(七)
2015-08-02 22:35
471 查看
目前的u-boot启动后有如下信息:
Net: CS8900-0
Error: CS8900-0address not set.
板子上的是DM9000不是CS8900,网卡模块肯定是错误的嘛。看到这里,你应该有了熟悉的思路,grep "Net:" * -nR查找网卡的初始化函数,经过筛选可以断定”Net:”实在这里打印的:
common/board_r.c:581: puts("Net: ");
连续跟踪可以发现如下结构:
最终发现了cs8900网卡的初始化函数cs8900_initialize,问题是找到了,但是不知道怎么修改啊!不要担心,别的开发板肯定有使用DM9000的,我们模仿其他开发板的使用方法。
搜索发现u-boot中有对DM9000支持的.c文件dm9000x.c,所以打开对应的Makefile看看dm9000x.c有没有被编译进u-boot:
所以要在smdk2440.h中取消CONFIG_CS8900宏增加CONFIG_DRIVER_DM9000宏:
make编译,出现大量错误:
可以看到这些错误都是没有定义DM9000_DATA、DM9000_IO宏造成的,也不知道这两个宏是干啥的,grep查看一下:
DM9000_DATA出现在很多头文件中,任意打开两个头文件可以看到:
可以猜测的是我们使用DM9000至少也要定义CONFIG_DM9000_BASE、DM9000_IO和DM9000_DATA,所以在smdk2440中添加这三个宏测试编译能不能通过。
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做如下修改:
make编译通过。
之前在board_eth_init函数中有对cs8900进行初始化的函数cs8900_initialize,现在取消CONFIG_CS9000的宏后连cs8900_initialize都不执行了。这个时候很容易想到这里应该替换成DM9000的初始化函数。而这个初始化函数当然是在dm9000x.c中,打开dm9000x.c可以看到有dm9000_initialize函数。使用grep查看dm9000_initialize的用法:
所以模仿上面的用法可以修改board/samsung/smdk2440/smdk2440.c中的board_eth_init函数为:
make编译下载到NorFlash并启动。可以看到:
Net: dm9000
这就代表DM9000可能移植成功了,具体是不是真的移植成功需要使用命令验证,最简单的方法就是ping。
到此,DM9000网卡移植完成。
下一节mtdparts命令支持
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 |
搜索发现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 |
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 |
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) |
root@ubuntu:/home/uboot/u-boot-2015.07-rc3# grep "DM9000_DATA" * -nR |
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) |
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 |
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) |
之前在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中: 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 |
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命令支持
相关文章推荐
- 移植u-boot-2015.07-rc3之增加smdk2440开发板框架支持(一)
- 移植u-boot-2015.07-rc3之修改代码支持SDRAM和SPL启动(二)
- 移植u-boot-2015.07-rc3之修改代码支持串口(三)
- 移植u-boot-2015.07-rc3之修改代码支持NorFlash(四)
- 移植u-boot-2015.07-rc3之修改代码支持NorFlash启动并真正支持NorFlash读写(五)
- 移植u-boot-2015.07-rc3之修改代码支持NandFlash(六)
- 移植u-boot-2015.07-rc3之uboot裁剪及启动参数修改(九)
- 移植u-boot-2015.07-rc3之修改代码支持mtdparts命令(八)
- 借助GD库和session制作图片验证码
- spring MVC return "redirect:test.do" 传参数
- c++中的函数重载
- java常识(列表更新中)
- Java学习笔记---一些关键字的使用
- 关于C++ const 的全面总结
- iOS开发分分钟搞定C语言 —— 结构体和枚举
- Python select模块学习
- 挖掘机技术哪家强(c++实现)
- eclipse 创建maven项目设置默认jdk版本
- 什么是PHP Guzzle?