主题 : linux-2.6.38到tiny6410的移植手册(连载2)__网卡&NFS 复制链接 | 浏览器收藏 | 打印
一路走好,下辈子再也不做程序员
级别: 侠客
UID: 32071
精华: 6
发帖: 38
金钱: 490 两
威望: 98 点
贡献值: 6 点
综合积分: 196 分
注册时间: 2010-11-09
最后登录: 2019-10-18
楼主  发表于: 2011-07-28 16:50

 linux-2.6.38到tiny6410的移植手册(连载2)__网卡&NFS

管理提醒: 本帖被 xoom 执行加亮操作(2011-08-11)
linux-2.6.38到tiny6410的移植手册(连载1)__nand flash
http://www.aiothome.net/read.php?tid-14196-fpage-2.html

linux-2.6.38到tiny6410的移植手册(连载2)__网卡&NF
http://www.aiothome.net/read.php?tid-14211.html

linux-2.6.38到tiny6410的移植手册(连载3)__ LCD&触摸屏
http://www.aiothome.net/read.php?tid=14261

linux-2.6.38到tiny6410的移植手册(连载4)__USB设备
http://www.aiothome.net/read.php?tid=14462

今天做的是dm9000网卡移植,和nfs文件系统的搭建

1、vi include/linux/dm9000.h
28行增加
unsigned char    param_addr[6];

2、vi arch/arm/mach-s3c64xx/mach-mini6410.c

为方便起见,将他的网卡结构体注释掉
#if 0
static struct resource mini6410_dm9k_resource[] = {
        [0] = {
                .start  = S3C64XX_PA_XM0CSN1,
                .end    = S3C64XX_PA_XM0CSN1 + 1,
                .flags  = IORESOURCE_MEM
        },
        [1] = {
                .start  = S3C64XX_PA_XM0CSN1 + 4,
                .end    = S3C64XX_PA_XM0CSN1 + 5,
                .flags  = IORESOURCE_MEM
        },
        [2] = {
                .start  = S3C_EINT(7),
                .end    = S3C_EINT(7),
             .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
        }
};

static struct dm9000_plat_data mini6410_dm9k_pdata = {
        .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
};

static struct platform_device mini6410_device_eth = {
        .name           = "dm9000",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(mini6410_dm9k_resource),
        .resource       = mini6410_dm9k_resource,
        .dev            = {
                .platform_data  = &mini6410_dm9k_pdata,
        },
};

#endif

增加

#define S3C64XX_PA_DM9000       (0x18000000)
#define S3C64XX_SZ_DM9000       SZ_1M
#define S3C64XX_VA_DM9000       S3C_ADDR(0x03b00300)

static struct resource dm9000_resources[] = {
        [0] = {
                .start          = S3C64XX_PA_DM9000,
                .end            = S3C64XX_PA_DM9000 + 3,
                .flags          = IORESOURCE_MEM,
        },
        [1] = {
                .start          = S3C64XX_PA_DM9000 + 4,
                .end            = S3C64XX_PA_DM9000 + S3C64XX_SZ_DM9000 - 1,
                .flags          = IORESOURCE_MEM,
        },
        [2] = {
                .start          = IRQ_EINT(7),
                .end            = IRQ_EINT(7),
                .flags          = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
        },
};

static struct dm9000_plat_data dm9000_setup = {
        .flags                  = DM9000_PLATF_16BITONLY,
        .dev_addr               = { 0x08, 0x90, 0x00, 0xa0, 0x90, 0x90 },
};

static struct platform_device s3c_device_dm9000 = {
        .name                   = "dm9000",
        .id                             = 0,
        .num_resources  = ARRAY_SIZE(dm9000_resources),
        .resource               = dm9000_resources,
        .dev                    = {
                .platform_data = &dm9000_setup,
        }
};

如果不嫌麻烦,也可以直接在原代码上改,S3C64XX_PA_XM0CSN1的值也为0x18000000的。

增加mac地址设置函数
static int __init dm9000_set_mac(char *str) {
        unsigned char addr[6];
        unsigned int val;
        int idx = 0;
        char *p = str, *end;
        while (*p && idx < 6) {
                val = simple_strtoul(p, &end, 16);
                if (end <= p) {
                        /* convert failed */
                        break;
                } else {
                        addr[idx++] = val;
                        p = end;
                        if (*p == ':'|| *p == '-') {
                                p++;
                        } else {
                                break;
                        }
                }
        }
         if (idx == 6) {
                printk("Setup ethernet address to %pM\n", addr);
                memcpy(dm9000_setup.param_addr, addr, 6);
        }

        return 1;
}

__setup("ethmac=", dm9000_set_mac);

    增加IO映射
增加映射结构体
static struct map_desc mini6410_iodesc[] = {
#ifdef CONFIG_DM9000
        {
                .virtual        = (u32)S3C64XX_VA_DM9000,
                .pfn            = __phys_to_pfn(S3C64XX_PA_DM9000),
                .length         = S3C64XX_SZ_DM9000,
                .type           = MT_DEVICE,
        },
#endif
};
然后在static void __init mini6410_map_io(void)函数中
将s3c64xx_init_io(NULL, 0);改成
  s3c64xx_init_io(mini6410_iodesc, ARRAY_SIZE(mini6410_iodesc));

最后在static struct platform_device *mini6410_devices[] __initdata 的初始化设备中
将     &mini6410_device_eth,
改成   &s3c_device_dm9000,

3、vi drivers/net/dm9000.c
大概1586行
将mac_src = "platform data";
memcpy(ndev->dev_addr, pdata->dev_addr, 6);

改成

  mac_src = "param data";
  memcpy(ndev->dev_addr, pdata->param_addr, 6);

大概1598行
增加
   if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
                mac_src = "platform data";
                memcpy(ndev->dev_addr, pdata->dev_addr, 6);
        }


4、make menuconfig
        [*] Networking support  --->
                Networking options  --->  
               <*> Packet socket                                                
                 <*> Unix domain sockets  
                [*] TCP/IP networking
                  [*]   IP: kernel level autoconfiguration                      
                      [*]     IP: DHCP support                                        
                          [*]     IP: BOOTP support                                        
                      [*]     IP: RARP support
    Device Drivers  --->
        [*] Network device support  --->
            [*]   Ethernet (10 or 100Mbit)  --->
                 <*>   DM9000 support  
            [ ]   Ethernet (1000 Mbit)  --->   去掉
其他的默认

编译出来,在引导信息中就能看到dm9000网卡信息了。

dm9000 Ethernet Driver, V1.31
eth0: dm9000a at d0930000,d0e00004 IRQ 108 MAC: 08:90:90:90:。。。。

5、增加NFS挂载功能
make menuconfig
    File systems  --->
        Network File Systems  --->
            <*>   NFS client support  
             [*]   Root file system on NFS   这个一点要选
            <*>   NFS server support

之后编译出来的内核就能挂载nfs文件系统了
我的是setenv bootargs console=ttySAC0 root=/dev/nfs nfsroot=58.154.51.164:/root/my_root ip=58.154.51.199:58.154.51.164:58.154.51.199:255.255.255.0 :kiss:eth0:off


mmc1: mmc_rescan_try_freq: trying to init card at 100000 Hz
eth0: link down
eth0: link up, 100Mbps, full-duplex, lpa 0xC1E1
IP-Config: Complete:
     device=eth0, addr=58.154.51.199, mask=255.255.255.0, gw=58.154.51.199,
     host=58.154.51.199, domain=, nis-domain=(none),
     bootserver=58.154.51.164, rootserver=58.154.51.164, rootpath=
VFS: Mounted root (nfs filesystem) on device 0:11.
Freeing init memory: 120K


Please press Enter to activate this console. [root@kissBaofish /]#
[root@kissBaofish /]#
[root@kissBaofish /]#
[root@kissBaofish /]#
[ 此帖被prettybxp在2011-08-09 23:10重新编辑 ]
一路走好,下辈子再也不做程序员
级别: 新手上路
UID: 27676
精华: 0
发帖: 38
金钱: 190 两
威望: 38 点
贡献值: 0 点
综合积分: 76 分
注册时间: 2010-08-30
最后登录: 2013-06-24
1楼  发表于: 2012-01-07 18:18
谢谢prettybxp~
NFS文件系统挂载成功,说明一下我的步骤:
开发板:tiny6410
linux主机:Ubuntu 11.10
说明:依据参考资料(http://www.aiothome.net/read.php?tid-14211.html,《tiny6410Linux开发指南》1.3.4 配置网络文件系统NFS服务)的说明,在linux-2.6.38,内核中依次添加了nand、yaffs2文件系统补丁(非必须)、DM9000网口组件、NFS文件系统支持,可以成功启动内核,获取IP地址,进入NFS文件系统。
测试办法:通过在SD卡中的superboot引导开发板启动,串口打印出superboot控制选项,设置superboot参数(详情见下文);然后在win7下,运行DNW下载工具,通过USB依次下载开发板tiny6410光盘B自带的已经编译好的u-boot,自己编译的内核镜像zImage,最后让superboot启动系统即可。
以上提到的工具组件等,由开发板厂商友善之臂提供的有:superboot、u-boot、DNW、文件系统,以及tiny6410开发板

详细步骤如下:

1、在linux主机上,准备文件系统
(1)复制开发板光盘tiny6410A-201110/Linux/rootfs_qtopia_qt4-20111018.tgz到Linux主机下,该tgz文件即为压缩后的文件系统;
(2)解压该文件系统到NFS共享目录下,生成rootfs_qtopia_qt4文件夹,该文件夹内为tiny6410的根文件系统,本次试验文件系统的位置在,主机:/home/a4/tiny6410portlinux2638/targetNFS/rootfs_qtopia_qt4
(3)开放文件夹rootfs_qtopia_qt4的权限为所有用户可读写执行(此步可能不需要,因为该文件的读写执行属性可以由NFS配置时设定)
host$chmod 777 rootfs_qtopia_qt4

2、在linux主机上,准备NFS服务器
(1)安装NFS服务器
host$sudo apt-get install nfs-kernel-server
(2)配置NFS服务器
host$sudo gedit /etc/exports
第一次打开该文件是空的,输入:
/home/a4/tiny6410portlinux2638/targetNFS/rootfs_qtopia_qt4 *(rw,sync,no_root_squash)
* 表示所有的客户机都可以挂接此目录,也可以限定一定的IP范围,如192.168.52.*,甚至为具体IP的客户机
rw 表示挂接此目录的客户机对该目录有读写的权力
no_root_squash 表示允许挂接此目录的客户机享有该主机的root身份
(3)启动NFS服务器
host$sudo /etc/init.d/nfs-kernel-server start
确定NFS服务器启动
host$sudo /etc/init.d/nfs-kernel-server status
nfsd running
Ubuntu 11.10启动时默认启动NFS。

3、启动tiny6410,并在其串口终端下配置superboot或u-boot
在superboot或u-boot命令行下,输入命令s并回车
接着输入:
console=ttySAC0 root=/dev/nfs nfsroot=IP0:/home/a4/tiny6410portlinux2638/targetNFS/rootfs_qtopia_qt4 ip=IP1:IP0:IP2:IP3:nameofyoulike:eth0:off
各参数的含义如下:
nfsroot是开发主机的IP地址,如果你使用了虚拟机,该地址是虚拟机中linux的IP地址,总之,它是直接提供NFS服务的Linux系统IP地址。
其中:
第一项(IP1)是目标板的临时IP(注意不要和局域网内其他IP冲突);
第二项(IP0)是开发主机的IP;
第三项(IP2)是目标板上网关(GW)的设置,这个参数设置为跟主机网关一直;
第四项(IP3)是子网掩码;
第五项(nameofyoulike)是开发主机的名字(一般无关紧要,可随便填写)
eth0是网卡设备的名称。
在superboot或u-boot命令行下,输入命令b并回车,系统即可启动并加载NFS文件系统。

4、附加实验-快速切换NFS文件系统或yaffs2文件系统
鉴于本次试验之前已经在NAND Flash中烧写了yaffs2文件系统,所以可以通过设置启动参数来切换选择NFS或yaffs2文件系统。
切换为yaffs2文件系统具体操作:在superboot或u-boot下,设置启动参数为:root=/dev/mtdblock2 console=ttySAC0,115200
切换为yaffs2文件系统的启动参数为:console=ttySAC0 root=/dev/nfs nfsroot=IP0:/home/a4/tiny6410portlinux2638/targetNFS/rootfs_qtopia_qt4 ip=IP1:IP0:IP2:IP3:nameofyoulike:eth0:off