S3C2440嵌入式Linux下网卡DM9000E移植

2019-07-13 05:30发布

mini2440上移植DM9000E网卡的参考步骤如下: 一、看电路图 mini2440开发板上移植好Linux-2.6.29.1内核和根文件系统的基础上,进行网卡DM9000E的移植,因为手里面有韦东山写的《嵌入式Linux应用开发完全手册》一书,在书中找到了DM9000网卡移植部分,对照该书与友善光盘里面的原理图,移植之前先从看原理图开始。看了DM9000ES3C2440的电路图发现: 1DM9000E挂接到S3C2440总线 S3C2440通过总线来访问DM9000Emini2440访问DM9000E的物理地址的基址是BANK4,用到一条地址线ADDR2,对应DM9000ECMD引脚,,因为DM9000E的地址信号和数据信号复用,CMD引脚决定传输的是地址信号还是数据信号,于是地址线ADDR2的引脚状态决定了DM9000ES3C2440传输的是地址信号还是数据信号。 2、总线位宽16,用到nWAIT信号 3DM9000E收到完整的数据包,通过中断引脚通知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.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,虚拟机的ip192.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驱动。