在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网卡的友好支持。
一些低版本的内核(比如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.cdm9000.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 __devinitdm9000_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,使能nWAIToldval_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))#elseif(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 interfacedm9000 dm9000.0: WARNING: no IRQ resource flags set.eth0: link up, 10Mbps, half-duplex, lpa 0x0021***************************************************************Studying ARM*********************Kernel version:linux-2.6.29.1Student:Feng dong ruiDate:2009.07.15***********************************************Please press Enter to activate this console. [MrFeng]#1、测试Please press Enter to activate this console. [MrFeng]#ifconfig -aeth0 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.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:1506 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions: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.0UP LOOPBACK RUNNING MTU:16436 Metric:1RX packets:6 errors:0 dropped:0 overruns:0 frame:0TX packets:6 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:504 (504.0 B) TX bytes:504 (504.0 B)[MrFeng]#ping 127.0.0.1PING 127.0.0.1 (127.0.0.1): 56 data bytes64 bytes from 127.0.0.1: seq="0" ttl="64" time="1".004 ms64 bytes from 127.0.0.1: seq="1" ttl="64" time="0".518 ms64 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 lossround-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 bytes64 bytes from 192.168.1.103: seq="0" ttl="64" time="2".098 ms64 bytes from 192.168.1.103: seq="1" ttl="64" time="1".342 ms64 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 lossround-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 /mntpic.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的书也不可能在一本书上讲得详细,但我每想做什么就不自觉的翻阅它,对我来说非常具有参考价值。另外就是网上的一些热心网友的博客、帖子上的内容给了我很多参考,结合“百家之长”解决问题,网上的资料很多,不一一列举。以上为复制。今天步骤 1.按照韦东山写的《嵌入式Linux应用开发完全手册》,并把miniarm dm9000.c #if defined (CONFIG_ARCH_S3C2410)#endif 宏里的直接复制到 linux 2.6.34 dm9000.c中。开始图省事,把dm9000.c dm9000.h,直接替换,并把include/linux/netdevice.h 也替换,并不成功。还是按照韦东山自己修改,成功。2.修改文件系统 /etc/init.d/rcS 3.mount 成功4.试hello。ko驱动。