linux-2.6.20内核移植 AX88697 驱动

 1、修改arch/arm/目录下的Kconfig文件,增加ISA总线支持,使其在make menuconfig 时出现NE2000的网卡配置选项。
        config ARCH_S3C2410
        bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
        select GENERIC_GPIO
        select ISA
        help
          Samsung S3C2410X CPU based systems, such as the Simtec Electronics
          BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
          the Samsung SMDK2410 development board (and derivatives).
    2、修改include/asm-arm/arch-s3c2410文件夹下的map.h文件。加入AX88796的地址映射。
          #define S3C2410_VA_ISA_NET   S3C2410_ADDR(0x02100000)
          #define S3C2410_PA_ISA_NET   __phys_to_pfn(0x10000000)
          #define S3C2410_SZ_ISA_NET   SZ_1M
       说明:
       a、根据网上的资料,“#define S3C2410_VA_ISA_NET   S3C2410_ADDR(0x02100000)”的地址可以自己修改,
          只要不和别的虚拟地址冲突就行。 我有试过将起改成“#define S3C2410_VA_ISA_NET   (0xd1000000)”,
          也就是博创的2.4.18的定义,也可以正常启动。
       b、“#define S3C2410_PA_ISA_NET   __phys_to_pfn(0x10000000)”这句困扰了我很久。
           一开始我的定义是“#define S3C2410_PA_ISA_NET   (0x10000000)”,
           所以启动后系统就死在了网卡的初始化上,出现“Unable to handle kernel paging request at virtual address ”
           的错误。后来我上网查找资料, 才知道:原来实地址与虚地址的映射结构 smdk2410_iodesc 里有所变化。
           第二个参数从原来的 unsigned long physical 变为 unsigned long pfn (Page Frame Number 页帧号)。
           而从 smdk2410_iodesc 传入的S3C2410_PA_ISA_NET 仍然是一个 physical 值,因此出现以上的错误。
           只要在物理地址前加上“__phys_to_pfn”就可以解决这个问题。
    3、修改arch/arm/mach-s3c2410文件夹下的mach-smdk2410.c文件。在smdk2410_iodesc 中加入AX88796的地址信息。
          static struct map_desc smdk2410_iodesc[] __initdata = {
           /* nothing here yet */
          {
            .virtual        = S3C2410_VA_ISA_NET,
            .pfn          = S3C2410_PA_ISA_NET,
            .length        = S3C2410_SZ_ISA_NET,
            .type          = MT_DEVICE,
          }
        };
     4、修改网卡驱动的主要文件drivers/net/ne.c。
       a、添加头文件和定义
            #include <asm/system.h>
            #include <asm/io.h>
    /**********************************************************************/
            #include <linux/irq.h>
            #include <asm/arch-s3c2410/map.h>
            #include <asm/arch-s3c2410/regs-mem.h>
            #include <asm/arch-s3c2410/irqs.h>
            #include <asm/arch-s3c2410/hardware.h>
            #include <asm/arch-s3c2410/regs-gpio.h>
 
            #define AX88796_BASE   (vAX88796_BASE+0x200)
            #define AX88796_IRQ    IRQ_EINT2
            #define pAX88796_BASE    S3C2410_PA_ISA_NET
            #define vAX88796_BASE    S3C2410_VA_ISA_NET
            #define EXTINT_OFF  (IRQ_EINT4 - 4)
    /*********************************************************************/
      在static struct { const char *name8, *name16; unsigned char SAprefix[4];}
        bad_clone_list[] __initdata 中增加AX88796 的MAC地址前三位(不一定需要):
         {"AX88796", "NE2000-compatible", {0x08, 0x08, 0x08}},

     b、确保定义总线宽度为16位。
       将  #if defined(CONFIG_PLAT_MAPPI)
           #define DCR_VAL 0x4b
           #elif defined(CONFIG_PLAT_OAKS32R)  || /
             defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
           #define DCR_VAL 0x48      /* 8-bit mode */
           #else
           #define DCR_VAL 0x49
           #endif
       修改为
           #if 0
           #if defined(CONFIG_PLAT_MAPPI)
           #define DCR_VAL 0x4b
           #elif defined(CONFIG_PLAT_OAKS32R)  || /
             defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
           #define DCR_VAL 0x48      /* 8-bit mode */
           #else
           #endif
           #endif
           #define DCR_VAL 0x49

      c、在do_ne_probe函数中增加配置总线参数、基地址和中断的语句(其参数参考 刘淼 的书)
          static int __init do_ne_probe(struct net_device *dev)
         {
                unsigned long base_addr = dev->base_addr;
                #ifdef NEEDS_PORTLIST
                int orig_irq = dev->irq;
                #endif
      /**************************************************************************/
                static int once=0;
                if (once) {
                return -ENXIO;
                 }
                unsigned int value;
 
                value = __raw_readl(S3C2410_BWSCON);
                value &= ~(S3C2410_BWSCON_WS2|S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_32);
                value |= (S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_16);
                __raw_writel(value, S3C2410_BWSCON);
                value=0;
                value = (S3C2410_BANKCON_Tacs4|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh4|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6|S3C2410_BANKCON_PMCnorm);
                __raw_writel(value,S3C2410_BANKCON2);
                set_irq_type(AX88796_IRQ,IRQ_TYPE_LEVEL_LOW );
                s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
                s3c2410_gpio_pullup(S3C2410_GPF2, 0);
                if(base_addr==0){
                dev->base_addr = base_addr = AX88796_BASE ;
                dev->irq = AX88796_IRQ;
                once++;
                 }
        /**************************************************************************/
               SET_MODULE_OWNER(dev);
 
             /* First check any supplied i/o locations. User knows best. <cough> */
                if (base_addr > 0x1ff) /* Check a single specified location. */
                return ne_probe1(dev, base_addr);
                else if (base_addr != 0)    /* Don't probe at all. */
                return -ENXIO;
        d、修改ne_probe1函数
            增加自定义的网卡MAC地址(这个地址可以自行修改,但是MAC也有一定的规则,最重要的是千万不要把它配置为广播或组播地址,请参考网络的相关书籍):
           static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
          {
             int i;
             unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x12,0x27,0};  /******************/
             unsigned char SA_prom[32];
             int wordlength = 2;
             ......

            增加网卡MAC地址的配置语句,屏蔽通过EEPROM配置网卡的语句
               struct {unsigned char value, offset; } program_seq[] =
           {
              {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
              {0x48,   EN0_DCFG},    /* Set byte-wide (0x48) access. */
              {0x00,   EN0_RCNTLO},  /* Clear the count regs. */
              {0x00,   EN0_RCNTHI},
              {0x00,   EN0_IMR}, /* Mask completion irq. */
              {0xFF,   EN0_ISR},
              {E8390_RXOFF, EN0_RXCR},    /* 0x20  Set to monitor */
              {E8390_TXOFF, EN0_TXCR},    /* 0x02  and loopback mode. */
              {32, EN0_RCNTLO},
              {0x00,   EN0_RCNTHI},
              {0x00,   EN0_RSARLO},  /* DMA starting at 0x0000. */
              {0x00,   EN0_RSARHI},
              {E8390_RREAD+E8390_START, E8390_CMD},
            };
 
              for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
              outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
           }

        /*****************************************************************************/
          {
                unsigned char *ep;
                ep = (unsigned char * ) &ne_defethaddr[0];
                ne_defethaddr[5]++;
                for(i=0;i<6;i++) {
               SA_prom[i] = ep[i];
          }
               SA_prom[14] = SA_prom[15]=0x57;
               wordlength =2;
         }
      /**********************************************************************************/
        #if 0    /*************/
           for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
           SA_prom[i] = inb(ioaddr + NE_DATAPORT);
           SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
           if (SA_prom[i] != SA_prom[i+1])
           wordlength = 1;
        }
        #endif   /*************/
           if (wordlength == 2)
         {
        #if 0   /*************/
           for (i = 0; i < 16; i++)
           SA_prom[i] = SA_prom[i+i];
        /* We must set the 8390 for word mode. */
           outb_p(DCR_VAL, ioaddr + EN0_DCFG);
           start_page = NESM_START_PG;
       /*
          * Realtek RTL8019AS datasheet says that the PSTOP register
          * shouldn't exceed 0x60 in 8-bit mode.
          * This chip can be identified by reading the signature from
          * the  remote byte count registers (otherwise write-only)...
       */

          if ((DCR_VAL & 0x01) == 0 &&         /* 8-bit mode */
             inb(ioaddr + EN0_RCNTLO) == 0x50 &&
             inb(ioaddr + EN0_RCNTHI) == 0x70)
             stop_page = 0x60;
          else
             stop_page = NESM_STOP_PG;
     /**********************************************************************************/
        #endif  
            outb_p(0x49, ioaddr + EN0_DCFG);
            start_page = NESM_START_PG;
            stop_page = NESM_STOP_PG;
    /**********************************************************************************/
        } else {
           start_page = NE1SM_START_PG;
           stop_page  = NE1SM_STOP_PG;
        }

      屏蔽自定检测中断号的语句(参考 刘淼 的书):
      #if 0   /*************/
        if (dev->irq < 2)
        {
             unsigned long cookie = probe_irq_on();
             outb_p(0x50, ioaddr + EN0_IMR);  /* Enable one interrupt. */
             outb_p(0x00, ioaddr + EN0_RCNTLO);
             outb_p(0x00, ioaddr + EN0_RCNTHI);
             outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
             mdelay(10);        /* wait 10ms for interrupt to propagate */
             outb_p(0x00, ioaddr + EN0_IMR);      /* Mask it again. */
             dev->irq = probe_irq_off(cookie);
             if (ei_debug > 2)
             printk(" autoirq is %d/n", dev->irq);
             } else if (dev->irq == 2)
         /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
            or don't know which one to set. */
            dev->irq = 9;
       #endif   /*************/
           if (! dev->irq) {
           printk(" failed to detect IRQ line./n");
           ret = -EAGAIN;
           goto err_out;
         }
           AX88697的移植到此结束!

 

  按照与上一篇的做法,这样就完成了一个小系统的制作 可以支持USB的挂载,同时也可以ping同网络

  在虚拟机上 setup  选中 Firewall configuration  选择 NO FIREWALL 关闭防火墙

   System services 选中 nfs 退出

   vi /etc/exports

   加入 /  (rw)

          /home/nfs (rw)

    cd /etc/rc.d/init.d

    ./nfs start   启动nfs

   将主机IP设为 ifconfig eth0 192.168.0.1

   再开一终端 minicom -s 配置minicom为波特率为115200,无奇偶检验,8bit后 给开发板上电,系统正常起来后

   设置开发板IP为 ifconfig eth0 192.168.0.2

   ping 主机 可以和主机ping通

   修改/home/nfs文件夹的属性 chmod 777 /home/nfs

   在开发板终端中输入 mount -o nolock 192.168.0.1:/home/nfs /mnt

   即可完成把主机上的/home/nfs下的文件挂载到开发板的/mnt目录下。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值