原创 基于S3C2440嵌入式Linux下网卡DM9000E移植

2010-1-11 22:41 3536 11 13 分类: MCU/ 嵌入式

基于S<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />3C2440嵌入式Linux下网卡DM9000E移植<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


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网卡的友好支持。



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 <linux/dm9000.h>


#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<mach/regs-mem.h>


#endif


在《嵌入式Linux应用开发完全手册》一书中上面的#include<mach/regs-mem.h>#include <asm/arch-s3c2410/regs-mem.h>,这使得我编译通不过,被我改成#include<mach/regs-mem.h>后编译成功,这是不同版本内核文件的程序所在文件的差别造成。


(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自己也有时会出现如下问题:



    [ <c0039740>] (s3c_irq_demux_extint4t7+0x0/0xa8) from [ <c002d044>] (asm_do_IRQ+0x


    44/0x5c)


    r4:c03c2350


    [ <c002d000>] (asm_do_IRQ+0x0/0x5c) from [ <c002d824>] (__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


    [ <c007254c>] (setup_irq+0x0/0x248) from [ <c007294c>] (request_irq+0xb0/0xcc)


    [ <c007289c>] (request_irq+0x0/0xcc) from [ <c01a8f40>] (dm9000_open+0x16c/0x23c)


    [ <c01a8dd4>] (dm9000_open+0x0/0x23c) from [ <c024839c>] (dev_open+0xa8/0x10c)


    [ <c02482f4>] (dev_open+0x0/0x10c) from [ <c0248a20>] (dev_change_flags+0x98/0x164


    )


    r5:00000000 r4:c382b800


    [ <c0248988>] (dev_change_flags+0x0/0x164) from [ <c0284cb8>] (devinet_ioctl+0x2f0


    /0x708)


    r7:bed9ba88 r6:c39fdf00 r5:00000000 r4:ffffff9d


    [ <c02849c8>] (devinet_ioctl+0x0/0x708) from [ <c0286c1c>] (inet_ioctl+0xc0/0xf4)


    [ <c0286b5c>] (inet_ioctl+0x0/0xf4) from [ <c023ac14>] (sock_ioctl+0x1e4/0x244)


    [ <c023aa30>] (sock_ioctl+0x0/0x244) from [ <c00a4f30>] (vfs_ioctl+0x3c/0x84)


    r7:00000003 r6:00008914 r5:ffffffe7 r4:c2d1a420


    [ <c00a4ef4>] (vfs_ioctl+0x0/0x84) from [ <c00a51fc>] (do_vfs_ioctl+0x284/0x2a4)


    r6:00000000 r5:bed9ba88 r4:c2d1a420


    [ <c00a4f78>] (do_vfs_ioctl+0x0/0x2a4) from [ <c00a525c>] (sys_ioctl+0x40/0x5c)


    r7:00000036 r6:00008914 r5:fffffff7 r4:c2d1a420


    [ <c00a521c>] (sys_ioctl+0x0/0x5c) from [ <c002dc40>] (ret_fast_syscall+0x0/0x2c)


    r6:00000000 r5:00159dec r4:00159d5c


    出现这个问题的原因是我没将中断的触发方式按照默认的,没有改成上面修改的。


    (2)、挂载不了网络文件系统


    可能的原因:检查内核的配置中是否选中对NFS的支持,Linux主机是否能连通局域网并设置了共享目录,硬件的链接是否良好。还有就是Linux主机的防火墙是否关闭,nfs服务是否已经开启。


    六、参考资料


    在学习的过程中,参考了韦东山写的《嵌入式Linux应用开发完全手册》一书,该书我觉得虽然没有把很多东西讲得很详细,嵌入式Linux的书也不可能在一本书上讲得详细,但我每想做什么就不自觉的翻阅它,对我来说非常具有参考价值。另外就是网上的一些热心网友的博客、帖子上的内容给了我很多参考,结合“百家之长”解决问题,网上的资料很多,不一一列举。


    1986fdr@163.com

    PARTNER CONTENT

    文章评论2条评论)

    登录后参与讨论

    用户1398279 2009-8-15 12:15

    慢慢来,坚持下去肯定会有很多收获的,接触多了就感觉并不是很难了。

    用户1522964 2009-8-15 10:47

    谢谢分享,记号,买板子也有一段时间,一直没有什么进展,要多向你学习才得
    相关推荐阅读
    用户1398279 2010-07-08 00:12
    C语言共享库的制作
    C语言共享库的制作0推荐 作者:杨硕,华清远见嵌入式学院讲师。1)基本概念共享库也是.o文件的集合,但是这些文件由编译器按照一种特殊的方式生成(Linux中,共享库文件为"ELF"格式,共享库已经具备...
    用户1398279 2010-07-04 22:37
    Linux 2.6.11 MTD驱动情景分析
    Linux 2.6.11 MTD驱动情景分析最近几天为了熟悉linux的驱动开发,我选择了其MTD驱动做了一些研究。我能找到的文章中我觉得有些部分不够细致,所以我还是自己写了一部分分析,希望对别人也能...
    用户1398279 2010-05-05 14:25
    automake使用及库和头文件的链接
    automake使用及库和头文件的链接关于automake的实践今天弄了很久的automake,自动生成Makefile,这样写程序时就会方便很多。之前也花时间看过一次,但当时只是对着一个hello....
    用户1398279 2010-05-05 11:33
    HP总裁退休时的信件
    HP总裁退休时的信件<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />我有个有趣的观察...
    用户1398279 2010-04-23 18:04
    VMWare的NAT配置(包括DHCP和固定IP配置)
    NAT的DHCP配置:这个网上别人写过,自己实验了下,没有问题。1 .最重要的是你的两个服务必须开启:VMware DHCP Service 和VMware NAT Service。具体操作如下: 开...
    用户1398279 2010-04-23 10:48
    gcc命令objdump用法
    gcc命令objdump用法2009年03月29日 星期日 23:49gcc命令之 objdump ---------------objdump是用查看目标文件或者可执行的目标文件的构成的GCC工具-...
    EE直播间
    更多
    我要评论
    2
    11
    关闭 站长推荐上一条 /3 下一条