zoukankan      html  css  js  c++  java
  • linux-2.6.32在mini2440开发板上移植之DM9000网卡移植

                                                                移植DM9000 网卡驱动
    1 设备资源初始化
          Linux-2..6.32.2 已经自带了完善的DM9000 网卡驱动驱动(源代码位置:linux-2.6.32.2/
    drivers/net/dm9000.c),它也是一个平台设备,因此在目标平台初始化代码中,只要填写好相
    应的结构表即可,具体步骤如下:

    首先添加驱动所需的头文件dm9000.h:
    #include <linux/dm9000.h>

    再定义DM9000 网卡设备的物理基地址,以便后面用到:
    /* DM9000AEP 10/100 ethernet controller */
    #define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)
    再填充该平台设备的资源设置,以便和DM9000 网卡驱动接口配合起来,如下
    static struct resource mini2440_dm9k_resource[] = {
            [0] = {
                    .start = MACH_MINI2440_DM9K_BASE,
                    .end = MACH_MINI2440_DM9K_BASE + 3,
                    .flags = IORESOURCE_MEM
                   },
            [1] = {
                   .start = MACH_MINI2440_DM9K_BASE + 4,
                   .end = MACH_MINI2440_DM9K_BASE + 7,
                   .flags = IORESOURCE_MEM
                   },
            [2] = {
                  .start = IRQ_EINT7,
                  .end = IRQ_EINT7,
                  .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
                   }
    };
    /*
    * * * The DM9000 has no eeprom, and it's MAC address is set by
    * * * the bootloader before starting the kernel.
    * * */
    static struct dm9000_plat_data mini2440_dm9k_pdata = {
                      .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
    };
    static struct platform_device mini2440_device_eth = {
                     .name = "dm9000",
                     .id = -1,
                     .num_resources = ARRAY_SIZE(mini2440_dm9k_resource),
                     .resource = mini2440_dm9k_resource,
                    .dev = {
                    .platform_data = &mini2440_dm9k_pdata,
                      },
    };
    ;同时在mini2440 设备集中添加上面做好的网卡平台设备,如下红色部分

    static struct platform_device *mini2440_devices[] __initdata = {
                         &s3c_device_usb,
                         &s3c_device_lcd,
                         &s3c_device_wdt,
                         &s3c_device_i2c0,
                         &s3c_device_iis,
                         &mini2440_device_eth,
                         &s3c_device_nand,

                         &mini2440_device_eth 
    };

    这样,DM9000 平台设备的接口就填完了。

    note:关于这个结构体struct resource说明下,这里定义了网卡的资源,查看板子的电路图,可以发现网卡是挂在

    总线上的,而且地址处于bank4区域, 中断是用的外部中断7.

     

    2 调整DM9000 所用的位宽寄存器
        因为Linux-2.6.32.2 的DM9000 网卡驱动并不是专门为mini2440 准备的,所以还要在其源代码中做一些移植工作,如下步骤。
        打开linux-2.6.32.2/ drivers/net/dm9000.c,头文件处添加2410 相关的配置定义,如下红色部分:
    #include <asm/delay.h>
    #include <asm/irq.h>
    #include <asm/io.h>
    #if defined(CONFIG_ARCH_S3C2410)
    #include <mach/regs-mem.h>
    #endif
    #include "dm9000.h"
    在dm9000 设备的初始化函数中添加如下红色部分,这里是配置DM9000 所用片选总线的时序,因为mini2440 目前只有一个通过总线外扩的设备,在此设备驱动中直接修改相关的寄存器配置会更加容易理解一些,当然这部分也可以放到mach-mini2440.c 中,你可以自行实验一下,在此不再赘述。
    static int __init
    dm9000_init(void)
    {
    #if defined(CONFIG_ARCH_S3C2410)
    unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
    unsigned int oldval_bankcon4 = *(volatile unsigned int *)S3C2410_BANKCON4;
    *((volatile unsigned int *)S3C2410_BWSCON) =
    (oldval_bwscon & ~(3<<16)) | S3C2410_BWSCON_DW4_16 |
    S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;

    *((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
    #endif
    printk(KERN_INFO "%s Ethernet Driver, V%s ", CARDNAME, DRV_VERSION);
    return platform_driver_register(&dm9000_driver);
    }


    3 关于MAC 地址
    需要注意的是,本开发板所用的DM9000 网卡并没有外接EEPROM 用以存储MAC 地址,因此系统中的MAC 地址是一个“软”地址,也就是可以通过软件进行修改,可以随意改为其他值,在static int __devinit dm9000_probe(struct platform_device *pdev)函数中可以看出:/* try reading the node address from the attached EEPROM */;尝试从EEPROM 读取MAC 地址


    for (i = 0; i < 6; i += 2)
                dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
    if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
               mac_src = "platform data";
               memcpy(ndev->dev_addr, pdata->dev_addr, 6);
    }
    if (!is_valid_ether_addr(ndev->dev_addr)) {
    /* try reading from mac */
               mac_src = "chip";
               for (i = 0; i < 6; i++)
                          ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
    }
    ;使用“软”MAC 地址: 08:90:90:90:90:90
    memcpy(ndev->dev_addr, "x08x90x90x90x90x90", 6);
    if (!is_valid_ether_addr(ndev->dev_addr))
                dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please ""set using ifconfig ", ndev->name);
    实际上到此为止DM9000 就已经移植结束了。

    4 配置内核加入DM9000,并编译运行测试此时会带内核源代码目录,执行:
    #make menuconfig
    开始在内核中配置网卡驱动,依次选择如下菜单项
    Device Drivers --->Network device support ---> Ethernet (10 or 100Mbit) --->
    即可找到DM9000 的配置项,可以看到DM9000 已经被选中,这是因为Linux-2.6.32.2,默认的内核配置已经加入了DM9000 的支持

    然后执行:
    #make zImage
    最后生成arch/arm/boot/zImage 文件,使用”k”命令把它烧写到开发板,并使用默认的文件系统启动,在命令行终端运行ifconfig 命令可以看到eth0的信息。

    note:以上的移植过程主要是根据手册整理出来的。下面加入些个人的东西。关于加入的这几行

    unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
    unsigned int oldval_bankcon4 = *(volatile unsigned int *)S3C2410_BANKCON4;
    *((volatile unsigned int *)S3C2410_BWSCON) =
    (oldval_bwscon & ~(3<<16)) | S3C2410_BWSCON_DW4_16 |
    S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;

    *((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;

    是什么意思呢?

    S3C2410_BWSCON,S3C2410_BANKCON4这个其实就是BWSCON、BANKCON4的地址,前面对应的是映射过的地址,后面对应的是实际的物理地址,对于S3C2440,这个虚实地址映射关系其实很简单,就是加入了一个便宜。以S3C2410_BWSCON举个例子(或者说跟踪下这个的实现过程)

    #define S3C2410_BWSCON   S3C2410_MEMREG(0x0000)

    #define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))

    #define S3C24XX_VA_MEMCTRL S3C_VA_MEM

    #define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */

    #define S3C_ADDR(x) (S3C_ADDR_BASE + (x))

    #define S3C_ADDR_BASE (0xF4000000)

    其实S3C2410_BWSCON也就是F4200000,其是地址0x48000000的一个映射,这个关系就是增加了一个偏移。这个大家应该基本都知道。

    下面说,上面的程序干了啥,

    里面出现的几个宏定义如下所示:

    #define S3C2410_BWSCON_ST4               (1<<19)

    #define S3C2410_BWSCON_WS4             (1<<18)

    #define S3C2410_BWSCON_DW4_16              (1<<16)

    下面是BWSCON控制寄存器的第16到19位

    ST4 [19] Determines SRAM for using UB/LB for bank 4.

    0 = Not using UB/LB (The pins are dedicated nWBE[3:0])

    1 = Using UB/LB (The pins are dedicated nBE[3:0])

    0

    WS4 [18] Determines WAIT status for bank 4.

    0 = WAIT disable 1 = WAIT enable

    0

    DW4 [17:16] Determine data bus width for bank 4.

    00 = 8-bit 01 = 16-bit, 10 = 32-bit 11 = reserved

     

     下面是BANK4CON寄存器各个位的含义。

    Tacs [14:13] Address set-up time before nGCSn

    00 = 0 clock 01 = 1 clock

    10 = 2 clocks 11 = 4 clocks

    00

    Tcos [12:11] Chip selection set-up time before nOE

    00 = 0 clock 01 = 1 clock

    10 = 2 clocks 11 = 4 clocks

    00

    Tacc [10:8] Access cycle

    000 = 1 clock 001 = 2 clocks

    010 = 3 clocks 011 = 4 clocks

    100 = 6 clocks 101 = 8 clocks

    110 = 10 clocks 111 = 14 clocks

    Note: When nWAIT signal is used, Tacc ³ 4 clocks.

    111

    Tcoh [7:6] Chip selection hold time after nOE

    00 = 0 clock 01 = 1 clock

    10 = 2 clocks 11 = 4 clocks

    000

    Tcah [5:4] Address hold time after nGCSn

    00 = 0 clock 01 = 1 clock

    10 = 2 clocks 11 = 4 clocks

    00

    Tacp [3:2] Page mode access cycle @ Page mode

    00 = 2 clocks 01 = 3 clocks

    10 = 4 clocks 11 = 6 clocks

    00

    PMC [1:0] Page mode configuration

    00 = normal (1 data) 01 = 4 data

    10 = 8 data 11 = 16 data

     

    把上面要赋值的数据,转换成二进制位,一一对照看设定了什么功能。总的来说,就是设置时序,不具体说了

  • 相关阅读:
    centos创建本地yum仓库
    CentOSyum操作
    配置mysql5.5主从服务器(转)
    如何做好网站开发项目需求分析(转)
    我在寻求工作治理的方法(转)
    Centos下_MysqL5.7在使用mysqldump命令备份数据库报错:mysqldump: [Warning] Using a password on the command line interface can be insecure.
    Redis限制在规定时间范围内登陆错误次数限制
    Yaf框架的配置
    在Centos环境下安装兼容Apache2.4高版本SVN服务
    yaf框架加载全局公共函数
  • 原文地址:https://www.cnblogs.com/liuchengchuxiao/p/4329874.html
Copyright © 2011-2022 走看看