U-Boot移植DM9000網(wǎng)卡
一、移植環(huán)境
1.u-boot版本1.1.6
2.開(kāi)發(fā)板Jz2440(ARM9 S3C2440
NAND K9F2G08
SDRAM K4S561632 * 2
網(wǎng)卡 DM9000)
3.Linux: ubuntu 9.10
二、移植思路
查看u-boot-1.1.6源碼發(fā)現(xiàn),u-boot中已經(jīng)包含dm9000的驅(qū)動(dòng)文件dm9000x.c,所以我們只需要設(shè)置u-boot支持網(wǎng)卡就行??傮w思路主要完成以下幾件事情:
1.設(shè)置存儲(chǔ)控制器,也就是設(shè)置S3C2440的BANK以使用DM9000;
2.配置u-boot使用DM9000網(wǎng)卡;
3.設(shè)置IP、serverIP等。
三、設(shè)置存儲(chǔ)控制器
根據(jù)Jz2440開(kāi)發(fā)板的原理圖可知,DM9000網(wǎng)卡 使用的是BANK4,如圖3.1所示。
圖3.1 DM9000原理圖
由圖可知,DM9000網(wǎng)卡使用的片選信號(hào)是nGCS 4,也就說(shuō)明DM9000使用了BANK4。修改lowlevel_init.S(路徑:board/smdk2410/lowlevel_init.S)。
#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)
#if 0
#define B3_BWSCON (DW16 + WAIT + UBLB)
#endif
#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網(wǎng)卡,將BANK3注釋掉,修改數(shù)據(jù)寬度為16位,設(shè)置BANK4數(shù)據(jù)寬度16位,使用WAIT和nBE信號(hào)。
#define B4_Tacs 0x0
#define B4_Tcos 0x3
#define B4_Tacc 0x7
#define B4_Tcoh 0x1
#define B4_Tah 0x3
#define B4_Tacp 0x6
#define B4_PMC 0x0
根據(jù)DM9000數(shù)據(jù)手冊(cè)設(shè)置時(shí)序,具體見(jiàn)DM9000數(shù)據(jù)手冊(cè)。
四、配置u-boot使用DM9000網(wǎng)卡
修改配置文件smdk2410.h(路徑:include/configs/smdk2410.h)。
#if 0
#define CONFIG_DRIVER_CS8900 1
#define CS8900_BASE 0x19000300
#define CS8900_BUS16 1
#endif
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_DM9000_BASE 0x20000000
#define DM9000_DATA 0x20000004
#define DM9000_IO 0x20000000
注釋掉CS8900的信息,添加DM9000的配置信息。
宏定義CONFIG_DRIVER_DM9000為1表示配置使用DM9000網(wǎng)卡,u-boot編譯時(shí)會(huì)將DM9000相關(guān)的驅(qū)動(dòng)編譯進(jìn)去。其中0x20000000是DM9000的基址(BANK4),由于DM9000只有一條地址線CMD(LADDR2,見(jiàn)圖3.1)用于區(qū)別是數(shù)據(jù)還是地址(CMD為低時(shí)數(shù)據(jù)總線上傳輸?shù)氖堑刂沸盘?hào),CMD為高時(shí)傳輸?shù)氖菙?shù)據(jù)信號(hào)),所以DM9000_DATA為0x20000004,DM9000_IO為0x20000000。
五、設(shè)置IP、serverIP
在配置文件smdk2410.h(路徑:include/configs/smdk2410.h)中根據(jù)實(shí)際情況修改開(kāi)發(fā)板的IP地址,serverIP。
修改前:
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 10.0.0.110
#define CONFIG_SERVERIP 10.0.0.1
修改后:
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.6
#define CONFIG_SERVERIP 192.168.1.2
我的PC和開(kāi)發(fā)板使用路由器相連,PC IP地址為192.168.1.2,開(kāi)發(fā)板設(shè)置為192.168.1.6,保證在同一個(gè)網(wǎng)段就行。
增加ping命令:
#define CONFIG_COMMANDS
(CONFIG_CMD_DFL|
CFG_CMD_CACHE|
FG_CMD_REGINFO|
CFG_CMD_PING|
CFG_CMD_DATE|
CFG_CMD_ELF)
仿照CMD命令格式,我們使用CFG_CMD_PING增加對(duì)ping的支持。
六、遇到問(wèn)題vs解決方案
以上任務(wù)完成,在u-boot根目錄下編譯,編譯成功!
使用OpenJtag將編譯完成的u-boot.bin燒入開(kāi)發(fā)板運(yùn)行。u-boot啟動(dòng)后,使用print命令查看u-boot的參數(shù):
Jz2440 #print
bootdelay=3
baudrate=115200
ethaddr=08:00:3e:26:0a:5b
ipaddr=192.168.1.6
serverip=192.168.1.2
netmask=255.255.255.0
stdin=serial
stdout=serial
stderr=serial
看到開(kāi)發(fā)板的IP、serverIP已經(jīng)修改成功。我們使用ping命令ping一下PC 192.168.1.2。
Jz2440 #ping 192.168.1.2
dm9000 i/o: 0x20000000, id: 0x90000a46
MAC: 50:50:50:50:50:50
could not establish link
ping failed; host 192.168.1.2 is not alive
host is not alive ,ping不通,看來(lái)存在問(wèn)題!
上網(wǎng)搜索了很久,網(wǎng)上的都是教你屏蔽這一段代碼,屏蔽那一段代碼,然后就可以了,都沒(méi)有詳細(xì)的分析,看不大明白。后來(lái),通過(guò)研究高版本的u-boot,發(fā)現(xiàn)了問(wèn)題所在。
打開(kāi)高版本u-boot,u-boot-1.3.4中的dm9000x.c,可以看到如下更新說(shuō)明:
06/03/2008 Remy Bohmer <[url=mailtonux@bohmer.net]linux@bohmer.net[/url]>
-Fixed the driver to work with DM9000A.
發(fā)現(xiàn)DM9000驅(qū)動(dòng)在后續(xù)版本中更新了,老版本的(u-boot-1.1.6)對(duì)DM9000支持可能存在問(wèn)題。
發(fā)現(xiàn)了問(wèn)題,馬上更新試試看,復(fù)制u-boot-1.3.4中的dm9000x.c到u-boot-1.1.6中,覆蓋掉原來(lái)的dm9000x.c,然后編譯。
出現(xiàn)了錯(cuò)誤!
drivers/dm9000x.c:480: undefined reference to `is_zero_ether_addr
/drivers/dm9000x.c:480: undefined reference to `is_multicast_ether_addr
make: *** [u-boot] Error 1
很明顯,缺少兩個(gè)函數(shù)定義。網(wǎng)上搜索也沒(méi)有找到,干脆對(duì)u-boot-1.3.4建立SourceInsight工程搜索這兩個(gè)函數(shù)。發(fā)現(xiàn)這兩個(gè)函數(shù)都存在于net.h中(路徑:include/net.h)。
復(fù)制這兩個(gè)函數(shù),到自己的u-boot(目前為u-boot-1.1.6)的net.h中(路徑: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]);
}
然后編譯,通過(guò)!
燒寫(xiě)到開(kāi)發(fā)板,ping主機(jī)192.168.1.2:
Jz2440 # ping 192.168.1.2
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:5b
could not establish link
host 192.168.1.2 is alive
“host 192.168.1.2 is alive”, ping通了,DM9000移植OK!
七、網(wǎng)絡(luò)測(cè)試
1.測(cè)試tftp
通過(guò)tftp傳輸一個(gè)程序到內(nèi)存中運(yùn)行試試看。在主機(jī)上打開(kāi)tftp軟件,將leds.bin(運(yùn)行地址在0x30000000)放在tftp軟件目錄中,在u-boot界面,輸入命令:
Jz2440 #tftp 0x30000000 leds.bin
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:5b
could not establish link
TFTP from server 192.168.1.2; our IP address is 192.168.1.6
Filename leds.bin.
Load address: 0x30000000
Loading: #
done
Bytes transferred = 168 (a8 hex)
傳輸成功,在u-boot界面使用go命令運(yùn)行程序
Jz2440 #go 0x30000000
## Starting application at 0x30000000 ...
可以看到Jz2440開(kāi)發(fā)板上led已經(jīng)在循環(huán)閃爍了。
2.測(cè)試nfs
由于虛擬機(jī)Linux上開(kāi)啟了nfs服務(wù),虛擬機(jī)Linux IP為192.168.1.3,需要先更改serverIP。
Jz2440 #setenv serverip 192.168.1.3
Jz2440 #saveenv
然后將leds.bin放在nfs目錄,/work/nfs_root/,在u-boot界面使用nfs傳輸文件
Jz2440 #nfs 0x30000000 192.168.1.3:/work/nfs_root/leds.bin
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:5b
could not establish link
File transfer via NFS from server 192.168.1.3; our IP address is 192.168.1.6
Filename /work/nfs_root/leds.bin.
Load address: 0x30000000
Loading: #
done
Bytes transferred = 168 (a8 hex)
傳輸成功,在u-boot界面使用go命令運(yùn)行程序
Jz2440 #go 0x30000000
## Starting application at 0x30000000 ...
可以看到Jz2440開(kāi)發(fā)板上led已經(jīng)在循環(huán)閃爍了。
至此,DM9000網(wǎng)卡移植成功!
評(píng)論