当前位置:首页 > 服务器类 > Unix > > UNIX下设备驱动程序的基本结构

UNIX下设备驱动程序的基本结构

点击次数:31 次 发布日期:2008-11-29 16:25:07 作者:源代码网
源代码网推荐
---摘自《天极网学习中心》(

源代码网整理以下  字符设备接口支持面向字符的I/O操作,它不经过系统的快速缓存,所以它们负责管理自己的缓冲区结构。字符设备接口只支持顺序存取的功能,一般不能进行任意长度的I/O请求,而是限制I/O请求的长度必须是设备要求的基本块长的倍数。显然,本程序所驱动的串行卡只能提供顺序存取的功能,属于是字符设备,因此后面的讨论在两种设备有所区别时都只涉及字符型设备接口。设备由一个主设备号和一个次设备号标识。主设备号唯一标识了设备类型,即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅由设备驱动程序解释,一般用于识别在若干可能的硬件设备中,I/O请求所涉及到的那个设备。

源代码网整理以下  设备驱动程序可以分为三个主要组成部分:

源代码网整理以下(1)自动配置和初始化子程序,负责检测所要驱动的硬件设备是否存在和是否能正常工作。如果该设备正常,则对这个设备及其相关的、设备驱动程序需要的软件状态进行初始化。这部分驱动程序仅在初始化的时候被调用一次。
(2)服务于I/O请求的子程序,又称为驱动程序的上半部分。调用这部分是由于系统调用的结果。这部分程序在执行的时候,系统仍认为是和进行调用的进程属于同一个进程,只是由用户态变成了核心态,具有进行此系统调用的用户程序的运行环境,因此可以在其中调用sleep()等与进程运行环境有关的函数。
(3)中断服务子程序,又称为驱动程序的下半部分。在UNIX系统中,并不是直接从中断向量表中调用设备驱动程序的中断服务子程序,而是由UNIX系统来接收硬件中断,再由系统调用中断服务子程序。中断可以产生在任何一个进程运行的时候,因此在中断服务程序被调用的时候,不能依赖于任何进程的状态,也就不能调用任何与进程运行环境有关的函数。因为设备驱动程序一般支持同一类型的若干设备,所以一般在系统调用中断服务子程序的时候,都带有一个或多个参数,以唯一标识请求服务的设备。

源代码网整理以下  在系统内部,I/O设备的存取通过一组固定的入口点来进行,这组入口点是由每个设备的设备驱动程序提供的。一般来说,字符型设备驱动程序能够提供如下几个入口点:
(1)open入口点。打开设备准备I/O操作。对字符特别设备文件进行打开操作,都会调用设备的open入口点。open子程序必须对将要进行的I/O操作做好必要的准备工作,如清除缓冲区等。如果设备是独占的,即同一时刻只能有一个程序访问此设备,则open子程序必须设置一些标志以表示设备处于忙状态。
(2)close入口点。关闭一个设备。当最后一次使用设备终结后,调用close子程序。独占设备必须标记设备可再次使用。
(3)read入口点。从设备上读数据。对于有缓冲区的I/O操作,一般是从缓冲区里读数据。对字符特别设备文件进行读操作将调用read子程序。
(4)write入口点。往设备上写数据。对于有缓冲区的I/O操作,一般是把数据写入缓冲区里。对字符特别设备文件进行写操作将调用write子程序。
(5)ioctl入口点。执行读、写之外的操作。
(6)select入口点。检查设备,看数据是否可读或设备是否可用于写数据。select系统调用在检查与设备特别文件相关的文件描述符时使用select入口点。如果设备驱动程序没有提供上述入口点中的某一个,系统会用缺省的子程序来代替。对于不同的系统,也还有一些其它的入口点。

源代码网整理以下3.2、LINUX系统下的设备驱动程序

源代码网整理以下  具体到LINUX系统里,设备驱动程序所提供的这组入口点由一个结构来向系统进行说明,此结构定义为:
#include<linux/fs.h>
structfile_operations{
int(*lseek)(structinode*inode,structfile*filp,
off_toff,intpos);
int(*read)(structinode*inode,structfile*filp,
char*buf,intcount);
int(*write)(structinode*inode,structfile*filp,
char*buf,intcount);
int(*readdir)(structinode*inode,structfile*filp,
structdirent*dirent,intcount);
int(*select)(structinode*inode,structfile*filp,
intsel_type,select_table*wait);
int(*ioctl)(structinode*inode,structfile*filp,
unsignedintcmd,unsignedintarg);
int(*mmap)(void);

源代码网整理以下int(*open)(structinode*inode,structfile*filp);
void(*release)(structinode*inode,structfile*filp);
int(*fsync)(structinode*inode,structfile*filp);
};
其中,structinode提供了关于特别设备文件/dev/driver(假设此设备名
为driver)的信息,它的定义为:
#include<linux/fs.h>
structinode{
dev_ti_dev;
unsignedlongi_ino;/*Inodenumber*/
umode_ti_mode;/*Modeofthefile*/
nlink_ti_nlink;
uid_ti_uid;
gid_ti_gid;
dev_ti_rdev;/*Devicemajorandminornumbers*/
off_ti_size;
time_ti_atime;
time_ti_mtime;
time_ti_ctime;
unsignedlongi_blksize;
unsignedlongi_blocks;
structinode_operations*i_op;
structsuper_block*i_sb;
structwait_queue*i_wait;
structfile_lock*i_flock;
structvm_area_struct*i_mmap;
structinode*i_next,*i_prev;
structinode*i_hash_next,*i_hash_prev;
structinode*i_bound_to,*i_bound_by;
unsignedshorti_count;
unsignedshorti_flags;/*Mountflags(seefs.h)*/
unsignedchari_lock;
unsignedchari_dirt;
unsignedchari_pipe;
unsignedchari_mount;
unsignedchari_seek;
unsignedchari_update;
union{
structpipe_inode_infopipe_i;
structminix_inode_infominix_i;
structext_inode_infoext_i;
structmsdos_inode_infomsdos_i;
structiso_inode_infoisofs_i;
structnfs_inode_infonfs_i;
}u;
};

源代码网整理以下structfile主要用于与文件系统对应的设备驱动程序使用。当然,其它设备驱动程序也可以使用它。它提供关于被打开的文件的信息,定义为:
#include<linux/fs.h>
structfile{
mode_tf_mode;
dev_tf_rdev;/*neededfor/dev/tty*/
off_tf_pos;/*Curr.posninfile*/
unsignedshortf_flags;/*Theflagsargpassedtoopen*/
unsignedshortf_count;/*Numberofopensonthisfile*/
unsignedshortf_reada;
structinode*f_inode;/*pointertotheinodestruct*/
structfile_operations*f_op;/*pointertothefopsstruct*/
};

源代码网整理以下  在结构file_operations里,指出了设备驱动程序所提供的入口点位置,分别是:
(1)lseek,移动文件指针的位置,显然只能用于可以随机存取的设备。
(2)read,进行读操作,参数buf为存放读取结果的缓冲区,count为所要读取的数据长度。返回值为负表示读取操作发生错误,否则返回实际读取的字节数。对于字符型,要求读取的字节数和返回的实际读取字节数都必
须是inode->i_blksize的的倍数。
(3)write,进行写操作,与read类似。
(4)readdir,取得下一个目录入口点,只有与文件系统相关的设备驱动程序才使用。
(5)selec,进行选择操作,如果驱动程序没有提供select入口,select操作将会认为设备已经准备好进行任何的I/O操作。
(6)ioctl,进行读、写以外的其它操作,参数cmd为自定义的的命令。
(7)mmap,用于把设备的内容映射到地址空间,一般只有块设备驱动程序使用。
(8)open,打开设备准备进行I/O操作。返回0表示打开成功,返回负数表示失败。如果驱动程序没有提供open入口,则只要/dev/driver文件存在就认为打开成功。
(9)release,即close操作。设备驱动程序所提供的入口点,在设备驱动程序初始化的时候向系统进行登记,以便系统在适当的时候调用。LINUX系统里,通过调用register_chrdev向系统注册字符型设备驱动程序。register_chrdev定义为:
#include<linux/fs.h>
#include<linux/errno.h>
intregister_chrdev(u
源代码网供稿.

网友评论 (0)
会员中心
服务器类
本站推荐
服务器类之精华