网卡驱动学习笔记

为了加深印象,所以写一写,,linux内核太复杂了,要搞懂好像我是肯定搞不懂,,不过我感觉把它当做一个工具来用换是不算很难,,,

linux网络设备驱动程序体系结构分为4层,,

(1),网络协议接口层,向网络协议提供统一的发送数据、接收数据函数,dev_queue_xmit(),发送,netif_rx()函数接收数据,,,

因为这一层使得上层协议完全独立于硬件,这一层的内容linux中已经做好了,不需要我们改动。

(2)网络设备接口层,,向上一层协议接口层提供了用于描述具体网络设备属性和操作的net_device,,这个结构图组织了设备驱动中的各信息、各函数,从宏观上规划了具体操作硬件的设备驱动功能层的结构。

(3)设备驱动功能层,实现了net_device数据结构的具体成员,,这些成员可驱使硬件完成动作

(4)网络设备与媒介层,,,即数据发送接收的物理实体。。

对网卡进行移植,主要是对设备驱动层进行操作,,,就是所谓的驱动程序,,但是内核中已经有了这个程序的模板,所以移植的过程只需要改很少的部分就可以。

 

 在网卡驱动移植时,有一个关键知识就是平台设备驱动的问题,,platform,这是一种虚拟总线,,它的优点,我现在想是,实现了设备与驱动的分离,就是硬件描述和驱动程序的分离,,要移植它的驱动,,只需要在硬件描述的文件中添加这个设备的硬件信息,然后找到这个硬件的驱动程序,,,

 

  platform机制中有几个关键的数据结构,,

1,platform_device结构体

struct platform_device {
 const char * name;
 int  id;
 struct device dev;
 u32  num_resources;
 struct resource * resource;

 struct platform_device_id *id_entry;
};

这个结构体描述了设备的硬件信息,,移植时,可在mach-smdk2410.c中定义这个结构体类型的设备,并且赋值,

2,platform_driver结构体

struct platform_driver {
 int (*probe)(struct platform_device *);
 int (*remove)(struct platform_device *);
 void (*shutdown)(struct platform_device *);
 int (*suspend)(struct platform_device *, pm_message_t state);
 int (*suspend_late)(struct platform_device *, pm_message_t state);
 int (*resume_early)(struct platform_device *);
 int (*resume)(struct platform_device *);
 struct device_driver driver;
 struct platform_device_id *id_table;
};

这个结构体组织了驱动程序的实现结构,,在驱动程序中定义设备的这个类型的结构体,以及成员函数的实现,,

模块加载时执行platform_driver_register(&dm9000_driver);

这个函数的作用是注册平台设备驱动,,,它里面的功能主要是把定义的平台驱动的信息赋值到struct device_driver driver;结构中,这是一个更加通用的描述驱动程序结构的结构体,,赋值完之后driver_register(&drv_driver),,,,,据说加载平台驱动程序时会执行int (*probe)(struct platform_device *);函数,但是我还没找到哪执行的这个,,,

以后再研究了。。

 

移植网卡驱动主要有两步,

1.在BSP板文件中加入平台设备结构,,在/arch/arm/mach-s3c2440/mach-smdk2440.c中添加

/* DM9000 */
static struct resource s3c_dm9k_resource[] = {
[0] = {
.start = S3C2410_CS4,
.end = S3C2410_CS4 + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S3C2410_CS4 + 4,
.end = S3C2410_CS4 + 4 + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
}
};

这个结构定义了DM9000所用的资源,,两个内存空间,一个中断资源

添加

static struct dm9000_plat_data s3c_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};

该结构指定访问DM9000时,数据宽度为16位

添加

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

定义设备结构

在static struct platform_device *smdk2440_devices[] __initdata = {}中添加 &s3c_device_dm9000,系统启动时就会把这个数组中的设备注册到内核中,

然后记得在文件开头加入#include <linux/dm9000.h>,,

2,修改drivers/net/dm9000.c

在文件开头加入

#if defined(CONFIG_ARCH_S3C2410)
#include <mach/regs-mem.h>
#endif

然后修改dm9000_probe(struct platform_device *pdev)函数中的一些内容,,比如设置工作模式的寄存器值,,保存默认的寄存器值,比如设置MAC地址的值,这些我觉得没什么意思

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值