Linux下的驱动程序设计——入门篇

打开的设备在内核内部由设备文件结构标识,内核使用file_operations(文件操作)结构访问驱动程序的函数。每个文件都与自己的函数集相关联(通过包含在设备中指向file_operations结构的指针实现),这些操作主要负责系统调用的实现。用户进程利用系统调用对设备文件进行操作时,系统调用通过设备的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数,这就是Linux的设备驱动程序工作的基本原理。由此可见,编写设备驱动程序的主要工作就是编写file_operations中的子函数,完成对设备的操作。下面给出2.4系统内核中file_operations结构中所包括的操作以及相关的解释[17],具体的定义可以参看<linux/fs.h>文件。

struct  file_operations

loff_t  (*llseek)(struct file*, loff_t, int);

方法llseek用来修改文件的当前读写位置,并将新位置(正的)作为返回值返回。参数loff_t是一个“长偏移量”,即使在32位平台上也至少占用64位的数据宽度。出错时返回一个负的返回值。如果驱动程序没有设置这个函数,那么相对于文件末尾的定位操作就会失败,而其他的定位操作就会修改file结构中的位置计数器并正确返回。

ssize_t (*read)(struct file*,char *, size_t, loff_t *);

用来从设备中读取数据。当该函数指针被赋为NULL值时,将导致read系统调用出错并返回-EINVAl(“Invalid argument,非法参数”)。函数返回非负值表示成功读取的字节数。

ssize_t (*write)(struct file*,char *, size_t, loff_t *);

向设备发送数据,如果没有这个函数,write函数的调用会向调用程序返回-EINVAL,如果返回非负值,则表示成功写入的字节数。

int(*readdir)(struct file*,void *,filldir_t);

对于设备文件来说,这个字段应该为NULL。它仅用于读取目录,并且只对文件系统有用。

unsigned int(*poll)(struct file *,struct poll_table_struct *);

poll方法是pollselect这两个系统调用的后端实现。这两个系统调用可用来查询设备是否可读或者可写,或者出于某种特殊状态。这两个系统调用是可阻塞的,直至系统可读、可写或者到某种特殊状态为止。如果驱动程序没有定义它的poll方法,它所驱动的设备就会被认为既可读又可写,并且不会出于某种特殊状态,返回值是一个描述设备状态的位掩码。

int(*ioctl)(struct inode *, struct file *,unsigned int ,unsigned long);

系统调用ioctl提供了一种执行设备特定命令的方法(如格式化某个硬盘分区)。另外,内核还能识别部分的ioctl命令,而不必调用fops中的ioctl。如果设备不提供ioctl入口点,则对于任何内核未预先定义的请求,ioctl系统调用将返回错误(-ENOTTY,“No such ioctl for device,该设备无此ioctl命令”)。如果该设备方法返回一个非负值,那么相同的值会被返回给调用程序以表示调用成功。

int(*mmap)(struct file *,struct vm_area_struct *);

mmap用于请求将设备内存映射到进程地址空间。如果设备没有实现这个方法,那么mmap系统调用将返回-ENODEV

int(*open)(struct inode *,struct file *);

尽管这个始终是设备文件执行的第一个操作,但是却不要求驱动程序一定要声明这个方法,如果这个入口点为NULL,那么设备的打开操作永远成功,但是系统不会通知驱动程序。

int(*flush)(struct file *);

flush操作的调用发生在进程关闭设备文件描述符副本的时候,它应该执行设备上尚未完成的操作。目前flush仅仅用于网络文件系统代码中,如果flush被置为NULL,则它只是简单的不被调用。

int(*release)(struct inode *,struct file *);

file结构被释放时,将调用这个操作。与open相仿,也可以没有release

int*fsync)(struct inode *,struct dentry *,int;

该方法是fsync系统调用的后端实现,用户调用它来刷新待处理的数据。如果驱动程序没有实现这一方法,fsync系统调用就返回-EINVAL

int*fasync)(intstruct file *int);

这个操作用来通知设备,它的异步标志发生了变化。如果设备不支持异步通知,那么该字段可以为NULL

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值