Linux系统设备驱动设计和实现
Linux系统设备驱动设计和实现
摘 要: 设备驱动程序在Linux中占有很重要的位置,这些底层驱动程序为用户程序屏蔽了硬件设备工作的具体细节,本文通过对Linux设备驱动结构,设备驱动特点的研究,最终实现了RTL8019网卡驱动的设计与实现。
关键词: Linux;内核;设备驱动;RTL8019
文章编号:1007-0745(2009)12-0070-02
1引言
Linux通过设备驱动程序为应用程序提供了统一抽象的接口,从而隐藏了大量不同设备之间的区别和细节,在Linux中对硬件设备的操作和通常的文件一样,利用标准的文件操作可以对设备上进行打开、关闭、读取或者写入操作。
2Linux设备驱动结构
在系统内部,I/O设备的存/取通过一组固定的入口点来进行,这组入口点是由每个设备的驱动程序提供的[21]。定义于Linux/fs.h文件中的file_operation结构就是这样一组入口点[22],在Linux-2.6.13中它的定义如下:
struct file_operations {
struct module *owner
/*指向拥有本结构的module,用于内核维护模块的引用计数*/
ssize_t(*read)(struct file*,char*,size_t,loff_t*)
ssize_t(*write)(struct file*,const char*,size_t,loff_t*)
/*向字符设备写数据,返回的非负数表示成功写入的字节数,需要提供所写 内容指针*/
int(*readdir)(struct file*,void*,filldir_t)
unsigned int*poll)(struct file*,struct poll_table_struct*)
int(*ioctl)(struct inode*,struct file*,unsigned int,unsigned long)
int(*mmap)(struct file*,struct vm_area_struct?*)
/*将设备内存映射到进程地址空间,通常只有块设备驱动程序使用*/
int (*open)(struct inode*,struct file*)
int(*release)(struct inode*,struct file*)
/*关闭设备,释放资源。只有当设备文件的所有备份都被释放时,才进行release调用,而不是每次调用close时都执行*/
int(*lock)(struct file*,int,struct file_lock*)
ssize_t(*readv)(struct file*,const struct iovec*,unsigned long,loff_t*)
ssize_t(*writev)(struct file*,const struct iovec*,unsigned long,loff_t* ) }
3Linux驱动开发方法
驱动开发的流程基本上可以归纳为以下几步:
(1)定义主、次设备号或动态获取;
(2)实现初始化和相应清除函数;
(3)填充file_operations结构;
(4)注册中断并实现中断服务程序;
(5)静态编译进内核或是编译为模块来动态加载;
(6)生成设备节点文件。
实际开发中,在调试阶段往往会先将驱动以模块方式来编译加载,这样方便了调试,加快了开发效率。
4 RTL8019网卡驱动设计
基于S3C2410的RTL8019驱动程序实现:
(1)此驱动程序基于Linux2.6.13.4内核,首先,在内核中增加对RTL8019支持的功能子菜单,方法如下:
修改Linux 2.6.13.4./drivers/net/Kconfig文件。
(2)在/arch/arm/mach-s3c2410创建smdk2410.h文件,部分内容说明如下:
在本开发板上,网卡占用的是CPU的nGCS3片选信号,也就是在Bank3,根据处理器的地址空间定义,这个地址是0具体定义如下:
#define pSMDK2410_ETH_IO 0
由于本系统采用的是2.6内核,所以内核中的虚拟地址为0xe000000,具体定义如下:
#define vSMDK2410_ETH_IO 0xe0000000
(3)修改/arch/arm/mac