在mini2440上移植DM9000E網卡的參考步驟如下:
一、看電路圖
在mini2440開發板上移植好Linux-2.6.29.1核心和根檔案系統的基礎上,進行網卡DM9000E的移植,因為手裡面有韋東山寫的《嵌入式Linux應用開發完全手冊》一書,在書中找到了DM9000網卡移植部分,對照該書與友善光碟片裡面的原理圖,移植之前先從看原理圖開始。看了DM9000E與S3C2440的電路圖發現:
1、DM9000E掛接到S3C2440匯流排
S3C2440通過匯流排來訪問DM9000E。mini2440訪問DM9000E的物理地址的基址是BANK4,用到一條地址線ADDR2,對應DM9000E的CMD引腳,,因為DM9000E的地址訊號和資料訊號複用,CMD引腳決定傳輸的是地址訊號還是資料訊號,於是地址線ADDR2的引腳狀態決定了DM9000E與S3C2440傳輸的是地址訊號還是資料訊號。
2、匯流排位寬16,用到nWAIT訊號
3、DM9000E收到完整的資料包,通過中斷引腳通知S3C2440來接收資料包,與S3C2440相連的中斷引腳為EINT7。
二、網路卡驅動程式修改
修改核心中網路卡驅動程式時需要先結合所使用的核心,先查看當前核心是否支援該網卡,如果不支援需要尋找支援該網卡的驅動程式進行修改。我用的是Linux-2.6.29.1核心,該核心已經對DM9000E具有很好的支援了,這在核心的Documentation/networking/dm9000.txt中有對核心中dm9000驅動程式詳細地說明,其中如下部分說明Linux-2.6.29.1核心對DM9000E網卡的友好支援。
The driver supports three DM9000 variants, the DM9000E which is the first chip supported as well as the newer DM9000A and DM9000B devices. It is currently maintained and tested by Ben Dooks, who should be CC: to any patches for this driver.
一些低版本的核心(比如linux-2.6.13等)對DM9000E不支援,可以用其它核心版本的dm9000.c驅動程式添加到核心中,進行修改和配置。由於這裡使用的核心已經對DM9000E網卡具有很好的支援,只需簡單的配置和修改即可。
1、修改DM9000平台裝置
修改/arch/arm/plat-s3c24xx/common-smdk.c檔案
(1)、添加要包含的標頭檔
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
#include
#endif
(2)、添加DM9000的平台裝置結構
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
/*DM9000*/
static struct resource s3c_dm9k_resource[]={
[0] = {
.start = S3C2410_CS4, //ADDR2 = 0
.end = S3C2410_CS4 + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S3C2410_CS4 + 4, //ADDR2 = 1
.end = S3C2410_CS4 + 4 + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ,
}
};
static struct dm9000_plat_data s3c_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
static struct platform_device s3c_device_dm9k = {
.name = "dm9000",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_dm9k_resource),
.resource = s3c_dm9k_resource,
.dev = {
.platform_data = &s3c_dm9k_platdata,
}
};
#endif
(3)、將DM9000平台裝置加入核心裝置列表中
/* devices we initialise */
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
&s3c_device_dm9k,
#endif
};
2、修改drivers/net/dm9000.c
dm9000.c中包含dm9000_probe函數,該函數完成DM9000裝置的枚舉,dm9000_probe函數的介紹在《嵌入式Linux應用開發完全手冊》一書中詳細介紹。
(1)、添加必要的標頭檔
#if defined(CONFIG_ARCH_S3C2410)
#include
#endif
在《嵌入式Linux應用開發完全手冊》一書中上面的#include是#include ,這使得我編譯通不過,被我改成#include後編譯成功,這是不同版本核心檔案的程式所在檔案的差別造成。
(2)、在dm9000_probe中設定儲存空間使BANK4可用,設定預設MAC地址(也可以在根檔案系統啟動指令碼設定),添加的代碼如下:
/*
* Search DM9000 board, allocate space and register it
*/
static int __devinit
dm9000_probe(struct platform_device *pdev)
{
…
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon; //用來儲存BWSCON寄存器的值
unsigned int oldval_bankcon4; //用來儲存S3C2410_BANKCON4寄存器的值
#endif
…
#if defined (CONFIG_ARCH_S3C2410)
//設定BANK4:匯流排寬度為16,使能nWAIT
oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3dev_addr))
dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
"set using ifconfig/n", ndev->name);
#if defined(CONFIG_ARCH_S3C2410)
printk("Now use the default MAC address:08:90:90:90:90:90/n");
ndev->dev_addr[0] = 0x08;
ndev->dev_addr[1] = 0x90;
ndev->dev_addr[2] = 0x90;
ndev->dev_addr[3] = 0x90;
ndev->dev_addr[4] = 0x90;
ndev->dev_addr[5] = 0x90;
#endif
…
out:
printk("%s:not found (%d)./n",CARDNAME,ret);
#if defined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
*((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4;
#endif
(3)、指定註冊中斷時的觸發方式
dm9000_open(struct net_device *dev)
{
…
irqflags |= IRQF_SHARED;
#if defined (CONFIG_ARCH_S3C2410)
if(request_irq(dev->irq,&dm9000_interrupt,IRQF_SHARED|IRQF_TRIGGER_RISING,dev->name,dev))
#else
if(request_irq(dev->irq,&dm9000_interrupt,IRQF_SHARED,dev->name,dev))
#endif
//if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
return -EAGAIN;
…
}
三、在核心中增加對網卡DM9000的配置
在核心目錄下執行“make menuconfig”命令進行如下的配置:
Device Drivers--->
[*]Network device support--->
[*]Ethernet(10 or 100Mbit)--->
DM9000 support
[*]Networking support--->
Networking options--->
TCP/IP networking
IP:kernel leel autoconfiguration
//增加對nfs的支援
File systems--->
[*]Networking File Systems--->
NFS client support
[*]NFS client support for NFS version 3
[*]NFS client support for the NFSv3 ACL protocol extension
[*]Boot file system on NFS
[*]NFS server support
四、修改根檔案系統啟動指令碼rcS
在根檔案etc/init.d/rcS檔案中添加如下:
echo "network interface"
/sbin/ifconfig lo 127.0.0.1
/sbin/ifconfig eth0 192.168.1.230 up
route add default gw 192.168.1.1
五、測試和修改
至此,將修改過的核心和根檔案系統下載到mini2440開發板,啟動時出現如下資訊:
----------munt all----------------
network interface
dm9000 dm9000.0: WARNING: no IRQ resource flags set.
eth0: link up, 10Mbps, half-duplex, lpa 0x0021
***********************************************
****************Studying ARM*********************
Kernel version:linux-2.6.29.1
Student:Feng dong rui
Date:2009.07.15
***********************************************
Please press Enter to activate this console.
[MrFeng]#
1、測試
Please press Enter to activate this console.
[MrFeng]#ifconfig -a
eth0 Link encap:Ethernet HWaddr 10:23:45:67:89:AB
inet addr:192.168.1.230 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1506 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:101460 (99.0 KiB) TX bytes:0 (0.0 B)
Interrupt:51 Base address:0x8000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:504 (504.0 B) TX bytes:504 (504.0 B)
[MrFeng]#ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: seq="0" ttl="64" time="1".004 ms
64 bytes from 127.0.0.1: seq="1" ttl="64" time="0".518 ms
64 bytes from 127.0.0.1: seq="2" ttl="64" time="0".436 ms
^C
--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.436/0.652/1.004 ms
[MrFeng]#ping 192.168.1.103
PING 192.168.1.103 (192.168.1.103): 56 data bytes
64 bytes from 192.168.1.103: seq="0" ttl="64" time="2".098 ms
64 bytes from 192.168.1.103: seq="1" ttl="64" time="1".342 ms
64 bytes from 192.168.1.103: seq="2" ttl="64" time="0".823 ms
^C
--- 192.168.1.103 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.823/1.421/2.098 ms
//掛載網路檔案系統
[MrFeng]#mount -t nfs -o nolock 192.168.1.103:/opt/nfs /mnt
[MrFeng]#ls /mnt
pic.jpg
[MrFeng]#umount /mnt
[MrFeng]#ls /mnt
[MrFeng]#
註:在掛載網路檔案系統時先要在Linux系統下設定共用目錄才能在從開發板掛載該目錄,這裡已經在虛擬機器下Redhat9.0系統中的/opt下設定了共用目錄nfs,虛擬機器的ip為192.168.1.103,故通過mount -t nfs -o nolock 192.168.1.103:/opt/nfs /mnt命令掛載。
2、曾經出現的問題
(1)、ping不同區域網路內其它主機,ping自己也有時會出現如下問題:
[ ] (s3c_irq_demux_extint4t7+0x0/0xa8) from [ ] (asm_do_IRQ+0x
44/0x5c)
r4:c03c2350
[ ] (asm_do_IRQ+0x0/0x5c) from [ ] (__irq_svc+0x24/0xa0)
Exception stack(0xc2e2bd98 to 0xc2e2bde0)
bd80: 00000000 fb000000
bda0: 00000001 00000000 c03c2a18 00000033 40000013 00000080 00000033 00000000
bdc0: c39bfc80 c2e2be10 c2e2bdbc c2e2bde0 c007320c c0072748 60000013 ffffffff
r7:00000080 r6:00000010 r5:f4000000 r4:ffffffff
[ ] (setup_irq+0x0/0x248) from [ ] (request_irq+0xb0/0xcc)
[ ] (request_irq+0x0/0xcc) from [ ] (dm9000_open+0x16c/0x23c)
[ ] (dm9000_open+0x0/0x23c) from [ ] (dev_open+0xa8/0x10c)
[ ] (dev_open+0x0/0x10c) from [ ] (dev_change_flags+0x98/0x164
)
r5:00000000 r4:c382b800
[ ] (dev_change_flags+0x0/0x164) from [ ] (devinet_ioctl+0x2f0
/0x708)
r7:bed9ba88 r6:c39fdf00 r5:00000000 r4:ffffff9d
[ ] (devinet_ioctl+0x0/0x708) from [ ] (inet_ioctl+0xc0/0xf4)
[ ] (inet_ioctl+0x0/0xf4) from [ ] (sock_ioctl+0x1e4/0x244)
[ ] (sock_ioctl+0x0/0x244) from [ ] (vfs_ioctl+0x3c/0x84)
r7:00000003 r6:00008914 r5:ffffffe7 r4:c2d1a420
[ ] (vfs_ioctl+0x0/0x84) from [ ] (do_vfs_ioctl+0x284/0x2a4)
r6:00000000 r5:bed9ba88 r4:c2d1a420
[ ] (do_vfs_ioctl+0x0/0x2a4) from [ ] (sys_ioctl+0x40/0x5c)
r7:00000036 r6:00008914 r5:fffffff7 r4:c2d1a420
[ ] (sys_ioctl+0x0/0x5c) from [ ] (ret_fast_syscall+0x0/0x2c)
r6:00000000 r5:00159dec r4:00159d5c
出現這個問題的原因是我沒將中斷的觸發方式按照預設的,沒有改成上面修改的。
(2)、掛載不了網路檔案系統
可能的原因:檢查核心的配置中是否選中對NFS的支援,Linux主機是否能連通區域網路並設定了共用目錄,硬體的連結是否良好。還有就是Linux主機的防火牆是否關閉,nfs服務是否已經開啟。
六、參考資料
在學習的過程中,參考了韋東山寫的《嵌入式Linux應用開發完全手冊》一書,該書我覺得雖然沒有把很多東西講得很詳細,嵌入式Linux的書也不可能在一本書上講得詳細,但我每想做什麼就不自覺的翻閱它,對我來說非常具有參考價值。另外就是網上的一些熱心網友的部落格、文章上的內容給了我很多參考,結合“百家之長”解決問題,網上的資料很多,不一一列舉。