程序项目代做,有需求私信(vue、React、Java、爬虫、电路板设计、嵌入式linux等)

linux驱动移植-DM9000网卡驱动以及NFS文件系统

Mini2440之linux内核移植文章中我们介绍了linux内核移植。并将最终修改后的内核代码保存到/work/sambashare/linux-5.2.8路径下。后续所有驱动也都将在这里修改。

root@zhengyang:/work/sambashare# ll
drwxrwxr-x 25 root root      4096 2月   7 12:11 linux-5.2.8/

之所以先介绍DM9000网卡驱动的移植,是因为内核支持了网卡芯片后,这样我们就可以使用nfs网络文件系统进行文件传输下载。

一、移植前述

实际上linux-5.2.8已经支持了Mini2440,并且在arch/arm/mach-s3c24xx目录下有mach-mini2440.c文件,它其实就是国外爱好者为Mini2440移植添加的主要内容。

在mach-mini2440.c的配置文件中,已经包含了网卡的平台驱动设备。

/* DM9000AEP 10/100 ethernet controller */

static struct resource mini2440_dm9k_resource[] = {
        [0] = DEFINE_RES_MEM(MACH_MINI2440_DM9K_BASE, 4),
        [1] = DEFINE_RES_MEM(MACH_MINI2440_DM9K_BASE + 4, 4),
        [2] = DEFINE_RES_NAMED(IRQ_EINT7, 1, NULL, 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,
        },
};

而且其支持的平台设备很多:

static struct platform_device *mini2440_devices[] __initdata = {
        &s3c_device_ohci,
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_rtc,
        &s3c_device_usbgadget,
        &mini2440_device_eth,
        &mini2440_led1,
        &mini2440_led2,
        &mini2440_led3,
        &mini2440_led4,
        &mini2440_button_device,
        &s3c_device_nand,
        &s3c_device_sdi,
        &s3c2440_device_dma,
        &s3c_device_iis,
        &uda1340_codec,
        &mini2440_audio,
};

后面我们驱动移植将会参考mach-mini2440.c文件。

二、DM9000网卡驱动移植

2.1 DM9000网卡硬件接线

Mini2440裸机开发之DM9000文章我们介绍到,在Mini2440的原理图:

  • DM9000只有一地址线CMD,地址线连接在S3C2440的ADDR2口上;
  • DM9000数据线SD0~SD15连接在S3C2440的LDATA0~LDATA15;
  • DM9000片选线是nLAN_CS(AEN),低电平有效。片选线连接在S3C2440的nGCS4上;

nGCS4对应的片选信号是0x20000000开头的,在0x20000000-0x28000000之间。所以当CPU发出0x20000000-0x28000000的物理地址数据时,DM9000就会被选中。

对于DM9000芯片来说,读写地址与数据使用的是同一组16个I/O引脚,DM9000芯片通过CMD引脚区分数据线传输的的是DM9000的寄存器地址,还是寄存器数据。

也就是说当CPU发出物理地址(0x20000000-0x28000000)| 0x4时,此时CPU再发出的数据线信号对于DM9000来说实际是地址信号。例如:

  • 当在地址0x20000000上读写数据时,表示读写的数据是DM9000的地址;
  • 当访问的地址0x20000004上读写数据时,表示读写的数据是DM9000的数据;

DM9000 IRQ_LAN(INT)接的是S3C2440的ENT7(GPF7),用的外部中断7,这个中断用于接收数据时触发的,高电平有效。

2.2  修改mach-smdk2440.c

linux-5.2.8已经自带了完善的DM9000网卡驱动(位于drivers/net/ethernet/davicom/dm9000.c),它也是一个平台设备,因此在目标平台初始化代码中,只要填写好相应的结构表即可。下面介绍具体步骤。

我们参考arch/arm/mach-s3c24xx/mach-mini2440.c,修改arch/arm/mach-s3c24xx/mach-smdk2440.c文件。

首先添加驱动所需的头文件dm9000.h:

#include <linux/dm9000.h>

再定义DM9000网卡设备的物理基地址:

#define MACH_SMDK2440_DM9K_BASE (S3C2410_CS4 + 0x300)

其中S3C2410_CS4定义如下:

arch/arm/mach-s3c24xx/include/mach/map.h:119:#define S3C2410_CS4 (0x20000000)

再填充该平台设备的资源设置,以便和 DM9000 网卡驱动接口配合起来:

/* DM9000AEP 10/100 ethernet controller */

static struct resource smdk2440_dm9k_resource[] = {
        [0] = DEFINE_RES_MEM(MACH_SMDK2440_DM9K_BASE, 4),
        [1] = DEFINE_RES_MEM(MACH_SMDK2440_DM9K_BASE + 4, 4),
        [2] = DEFINE_RES_NAMED(IRQ_EINT7, 1, NULL, 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 smdk2440_dm9k_pdata = {
        .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
};

static struct platform_device smdk2440_device_eth = {
        .name           = "dm9000",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(smdk2440_dm9k_resource),
        .resource       = smdk2440_dm9k_resource,
        .dev            = {
                .platform_data  = &smdk2440_dm9k_pdata,
        },
};

最后修改smdk2440_devices数组,添加:

&smdk2440_device_eth

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

2.3 编译下载运行

make clean
make s3c2440_defconfig

配置内核支持DM9000:

make menuconfig

设置:

Device Drivers --->
    [*] Network device support --->
          [*] Ethernet driver support --->
                <*> DM9000 support

即可找到DM9000的配置项,可以看到DM9000已经被选中,这是因为linux-5.2.8 默认的内核配置已经加入了DM9000的支持:

然后执行:

make uImage 

重新下载内核到开发板,运行如下命令查看网卡信息:

# ifconfig
eth0      Link encap:Ethernet  HWaddr 86:51:42:D9:D0:CC  
          inet addr:192.168.1.17  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 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:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:55 Base address:0x8300 

修改ip地址:

# ifconfig eth0 192.168.0.105
# ping 192.168.0.200
PING 192.168.0.200 (192.168.0.200): 56 data bytes
64 bytes from 192.168.0.200: seq=0 ttl=64 time=3.488 ms
64 bytes from 192.168.0.200: seq=1 ttl=64 time=1.526 ms
64 bytes from 192.168.0.200: seq=2 ttl=64 time=1.818 ms
64 bytes from 192.168.0.200: seq=3 ttl=64 time=1.797 ms
64 bytes from 192.168.0.200: seq=4 ttl=64 time=1.804 ms
64 bytes from 192.168.0.200: seq=5 ttl=64 time=1.792 ms
64 bytes from 192.168.0.200: seq=6 ttl=64 time=1.541 ms

192.168.0.200是ubuntu服务器的ip地址。

三、 NFS根文件系统支持

在之前的章节,我们介绍了linux内核支持yaffs2文件系统,但是这样有一个弊端,就是后面我们需要编写驱动程序啊,将程序添加到yaffs文件系统是非常不方便的。

使用NFS作为根文件系统,因为文件系统在宿主机中,这样在修改文件系统就非常方便,主要用于开发阶段使用。

3.1 内核配置

配置内核:

make menuconfig

设置:

File systems --->
    [*] Network File Systems --->
          <*> NFS client support for NFS version 4

勾选NFS client support for NFS version 4。

保存配置:

存档:

mv s3c2440_defconfig ./arch/arm/configs/

然后重新编译内核。

3.2 u-boot配置

在之前的章节,我们曾经搭建了NFS服务器,我们尝试通过nfs来挂载根文件系统rootfs,该文件系统位于/work/sambashare路径下。我们将根文件系统复制到nfs共享路径下:

cp -a /work/sambashare/rootfs /work/nfs_root/

下载uboot、linux到开发板中,u-boot启动后,设置启动参数(参数比较长,直接复制到串口发送可能会发生字符串错位等问题):

set bootargs "noinitrd console=ttySAC0,115200 root=/dev/nfs rw nfsroot=192.168.0.200:/work/nfs_root/rootfs ip=192.168.0.105:192.168.0.200:192.168.0.1:255.255.255.0::eth0:off"
save

其中:

  • root 表示使用/dev/nfs这个设备作为根文件系统。 rw 表示可读可写的;
  • nfsroot 表示服务器中rootfs所在路径,注意需要跟上服务器的ip地址;
  • 192.168.0.105 是板子启动之后的ip地址;
  • 192.168.0.200 是nfs服务器的ip地址;
  • 192.168.0.1 是板子网关地址;
  • 255.255.255.0 是板子子网掩码;

eth0表示板子上的网络设备。 off 表示关闭动态获取ip地址。 注意:eh0前面有两个冒号,那是因为这里还可以填写一个板子的主机名,这里没有设置,所以为空。 

然后输入命令,启动内核:

nand read 0x30000000 kernel
bootm 0x30000000

启动成功后输出信息如下:

参考文章

[1]S3C2440内核移植

[2]05-S3C2440学习之内核(移植)linux3.4.2移植(3)之支持DM9000C网卡及修改支持串口2

[3]二十一、Linux驱动之移植DM9000C网卡驱动(下)

posted @ 2022-02-10 21:55  大奥特曼打小怪兽  阅读(658)  评论(0编辑  收藏  举报
如果有任何技术小问题,欢迎大家交流沟通,共同进步