开发板:天嵌TQ2440
u-boot:u-boot-1.1.6
手里的开发板是天嵌的TQ2440,看的书是韦东山老师的《嵌入式Linux开发完全手册》,有些许不同的地方,增加了移植困得,当应该也更加深自己的理解。
这一讲是u-boot移植DM9000网卡
我们移植使用的SMDK2410中使用的网络PHY是CS8900,而我们TQ2440使用的PHY是DM9000,有些许差异,因此需要做移植改动。
首先我们来看一下DM9000与S3C2440的硬件连接。
从图中我们可以知道DM9000连接的是BANK4,因此其访问地址是从0x20000000开始的,另外在CMD接口连接的是LADDR2,因此DM9000的地址一共就两个即0x20000000(地址线)和0x20000004(数据线)。从地址线的连接可以知道数据通信时并行16bit。
接下来就是修改文件代码,实现适配了。
首先修改lowlevel_init.S(路径:board/smdk2410/lowlevel_init.S这个文件u-boot启动第一阶段对于Nor flash的操作,我们主要修改里面的时序相关)。
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
#define DW32 (0x2)
#define WAIT (0x1<<2)
#define UBLB (0x1<<3)
#define B1_BWSCON (DW32)
#define B2_BWSCON (DW16)
#define B3_BWSCON (DW16 + UBLB)
#define B4_BWSCON (DW16 + WAIT + UBLB)
#define B5_BWSCON (DW16)
#define B6_BWSCON (DW32)
#define B7_BWSCON (DW32)
修改前BANK3外接的CS8900网卡,修改BANK3,修改数据宽度为16位,设置BANK4数据宽度16位,使用WAIT和nBE信号。
#define B4_Tacs 0x0 /*0clk */
#define B4_Tcos 0x3 /*4clk */
#define B4_Tacc 0x7 /* 14clk */
#define B4_Tcoh 0x1 /*1clk */
#define B4_Tah 0x3 /*4clk */
#define B4_Tacp 0x6 /*6clk */
#define B4_PMC 0x0 /* normal */
根据DM9000数据手册设置时序,具体见DM9000数据手册。
接下来打开./include/configs/TQ2440.h这里面宏定义了我们使用网络芯片宏定义的芯片及接口信息等。我们根据自己的需要做出修改需要修改的地方如下。
将
#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 */
屏蔽掉,并添加DM9000定义代码
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_DM9000_BASE 0x20000000
#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
#define DM9000_IO CONFIG_DM9000_BASE
上面中DM9000_DATA定义不要忘记加括号,或者直接写0x20000004,否则的话编译会报错!!
接下来继续修改子网掩码,IP地址和网关,修改完后的三个数据如下所示。
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.200
#define CONFIG_SERVERIP 192.168.1.100
注意修改的IP地址和服务器IP需要在同一网段,即前三个数字相同。ipaddrip是开发板ip,一般serverip设置为电脑的IP。
最后在CONFIG_COMMANDS中添加PING命令,用于测试网络是否联通。添加之后的代码如下所示。
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
/*CFG_CMD_NAND |*/ \
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I2C |*/ \
/*CFG_CMD_USB |*/ \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_PING | \
CFG_CMD_ELF)
这样,对于TQ2440.h的修改已经全部完成了。
我们之前有谈到,SMDK2410原本只添加了对于CS8900的支持,现在我们想添加对DM9000支持是否还需要自己编写驱动代码呢?答案是不要,因此在./drivers路径下已经包含了DM9000的驱动文件(Dm9000x.c和Dm9000x.h)所以我们不需要任何操作了。
这个时候我们编译已经没有问题了。但是如果你下载就到Nor flash,会发现ping不通。根据网上大神给的说法是u-boot-1.1.6中给出的Dm9000的驱动是有问题。我们将u-boot-1.3.4中的./drivers/net/dm9000x.c复制到u-boot-1.1.6中./drivers/目录下。接下来make all,结果出现如下情况:
报错找不到is_zero_ether_addr和is_multicast_ether_addr两个函数。经过查找,发现在u-boot-1.3.4中这两个函数在./include/net.h文件中,如下所示。
static inline int is_zero_ether_addr(const u8 *addr)
{
return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
}
static inline int is_multicast_ether_addr(const u8 *addr)
{
return (0x01 & addr[0]);
}
我们直接把这两个函数复制到u-boot-1.1.6的./include/net.h文件中
最后我们make all,发现编译通过啦!!
接下来我们就是把u-boot.bin文件下载到nor flash中,然后看看是否可以ping通我们的电脑?这里首先解释一波。我上面设置服务器IP为192.168.1.100,TQ2440的ip为192.168.1.200。我为什么做如此设置呢?原因在于我的电脑通过路由器进行上网连接。路由器网关为192.168.1.1。路由器为我的电脑无线网卡分配的IP为192.168.1.100,与我电脑桥接的ubuntu虚拟机的IP为192.168.1.101。这下明白了吧。这小哥仨的IP是连着的。当我做ping实验时,网线一端连TQ2440,一端连接路由器。由于192.168.1.100、192.168.1.101、192.168.1.200三者目前是处于同一局域网中,因此理论上我们可以ping通192.168.1.100和192.168.1.101的,那么实际情况是如此吗?请看下图
图中1处我们先ping 了192.168.1.100,结果是alive说明ping通了。
图中2处我们ping 了192.168.1.101,结果是alive说明也ping通了。
这就与我们猜想完全一致,说明DM9000移植成功!!!
关于ping的这一块,还有一点就是,如果你是开发板与电脑之间是无线连接,那serverip就是无线连接的地址。如果开发板与电脑直接是完全的网线连接,那么serverip就是用线连接的地址,一般这种情况,你需要自己设置好ip,不然鬼知道电脑会自动把ip设成什么。
但是我们能止步于此吗?我们不能,我们还要追求诗和远方!啊不,是追求网卡的应用!
测试TFTP命令
首先我们来研究一下,使用tftp来下载程序。
之前我们已经通过ping命令来验证IP地址的有效性。那么我们如何通过TFTP来下载程序呢?
我们使用电脑上的TFTP server软件来完成下载。
首先在命令窗口重新设置我们要进行TFTP的服务器的地址,如下所示
TQ2440 # set serverip 192.168.1.100
因为我们之前在程序里已经设置了serverip为192.168.1.100所以,这一步我们可以不用操作。但是请注意我们使用的tftp命令是直接在ipaddr与serverip直接建立通信,在我们使用
好IP设置完后,我们打开TFTP server软件,在Settings设置好input和output的路径,这两个路径是我们上传下载文件的存放路径,这里我们把要下载到开发板里的程序led.bin放到output标签下设置的路径。然后turn on the server(即点击三角变绿,如下所示)
接下来,在命令窗口输入
tftp 0x30000000 led.bin
意思就是通过tftp向地址0x30000000下载led.bin文件。下载成功后的样子如下所示
可以看到发出命令后linux先列出一些下载信息,接着loading下载,下载完成后,显示done。同样的在TFTP server中也显示了finish信息。
最后一步在命令窗口,输入go 0x30000000,那么程序开始运行,灯开始闪烁啦!!
测试NFS命令
由于虚拟机Linux上开启了nfs服务,虚拟机Linux IP为192.168.1.101,需要先更改serverIP。
在命令输入窗口输入set serverip 192.168.1.101
然后将leds.bin放在nfs目录,/work/nfs_root/,在命令窗口使用nfs传输文件,如下所示
如上图所示,1为设置服务器地址,2为发送nfs命令,3处说明下载程序完成。4使用go 0x30000000命令运行程序
然后我们就看到led灯开始闪烁。
至此关于网络的tftp和nfs命令已经测试完成。dm9000移植成功!!!
参考文献:1、《嵌入式linux开发完全手册》、韦东山
2、http://blog.csdn.NET/zhaocj (这位博主下面的u-boot系列)
3、http://blog.sina.com.cn/s/blog_7a2a032b0100y2dz.html
4、http://blog.youkuaiyun.com/quannii/article/details/8861481