基於S3C2440嵌入式Linux下網卡DM9000E移植

在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 & ~(3<<16)) / | S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4; //設置BANK4的時間參數 oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4); *((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c; #endif … if (!is_valid_ether_addr(ndev->dev_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的書也不可能在一本書上講得詳細,但我每想做什麼就不自覺的翻閱它,對我來說非常具有參考價值。另外就是網上的一些熱心網友的博客、帖子上的內容給了我很多參考,結合“百家之長”解決問題,網上的資料很多,不一一列舉。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章