在开始编写驱动前,还需要学习一下驱动程序操作时一个重要的数据结构,file_operations。

在获取了一些设备编号后,我们还没有将任何驱动程序操作连接到这些编号,file_operations结构就是用来建立这种连接的。

这个结构定义在<linux/fs.h>中。

struct file_operations {struct module *owner;loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);int (*iterate) (struct file *, struct dir_context *);//int (*iterate_shared) (struct file *, struct dir_context *);//unsigned int (*poll) (struct file *, struct poll_table_struct *);long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);long (*compat_ioctl) (struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct file *);int (*flush) (struct file *, fl_owner_t id);int (*release) (struct inode *, struct file *);int (*fsync) (struct file *, loff_t, loff_t, int datasync);int (*fasync) (int, struct file *, int);int (*lock) (struct file *, int, struct file_lock *);ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);int (*check_flags)(int);int (*flock) (struct file *, int, struct file_lock *);ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);int (*setlease)(struct file *, long, struct file_lock **, void **);long (*fallocate)(struct file *file, int mode, loff_t offset,loff_t len);void (*show_fdinfo)(struct seq_file *m, struct file *f);
#ifndef CONFIG_MMUunsigned (*mmap_capabilities)(struct file *);
#endifssize_t (*copy_file_range)(struct file *, loff_t, struct file *,loff_t, size_t, unsigned int);int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t,u64);ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,u64);
};

这里面有很多地方都用到了__user字符。

它其实是一种形式的文档而已,表明指针是一个用户空间地址,因此不能被直接引用。对通常的编译来将,__user没有任何效果,但是可由外部检查软件使用,用来寻找对用户空间的错误使用。

struct module *owner;

第一个file_operations字段并不是一个操作,相反,它是一个指向拥有该结构的模块的指针。内核使用这个字段以避免在模块的操作正在被使用时卸载该模块。几乎在所有情况下,该成员都会被初始化为THIS_MODULE,它是定义在<linux/module.h>中的一个宏。

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

llseek 方法用作改变文件中的当前读/写位置, 并且新位置作为(正的)返回值。

(指针参数struct file *为进行读取信息的目标文件结构体指针;参数 loff_t 为文件定位的目标偏移量;参数int为对文件定位的起始地址,这个值可以为文件开头(SEEK_SET,0,当前位置(SEEK_CUR,1),文件末尾(SEEK_END,2))

loff_t 参数是一个"long offset", 并且就算在 32位平台上也至少 64 位宽. 错误由一个负返回值指示;如果这个函数指针是 NULL, seek 调用会以潜在地无法预知的方式修改 file结构中的位置计数器。

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

用来从设备中读取数据。该函数指针被赋值为NULL值时,将导致read系统调用出错并返回-EINVAL("Invalid argument,非法参数")。函数返回非负值表示成功读取的字节数(返回值为"signed size"数据类型,通常就是目标平台上的固有整数类型)。

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

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

ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);

异步的读取操作,在函数返回之前可能不会完成的读取操作。如果该函数为NULL,所有的操作将通过read(同步)处理。

linux 4.5版本前为:

ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);

异步写入操作。

linux 4.5版本前为:

ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

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

poll方法是poll、epoll和select这三个系统调用的后端实现。这三个系统调用可用来查询某个或多个文件描述符上的读取或写入是否被阻塞。poll方法应该返回一个位掩码,用来指出非阻塞的读取或写入是否可能,并且也会向内核提供将调用进程置于休眠状态直到I/O变为可能时的信息。如果驱动程序将poll方法定义为NULL,则设备会被认为即可读也可写,并且不会被阻塞。

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);

ioctl提供了一种执行设备特定命令的方法(如格式化软盘的某个磁道,这即不是读操作也不是写操作)。另外,内核还能识别一部分ioctl命令,而不必调用fops表中的ioctl。如果设备不提供ioctl入口点。这对于任何内核未预先定义的请求,ioctl系统调用将返回错误(-ENOTTY,“No such ioctl for device,该设备无此ioctl命令”)。

1、compat_ioctl:支持64bit的driver必须要实现的ioctl,当有32bit的userspace application call 64bit kernel的IOCTL的时候,这个callback会被调用到。如果没有实现compat_ioctl,那么32位的用户程序在64位的kernel上执行ioctl时会返回错误:Not a typewriter

2、如果是64位的用户程序运行在64位的kernel上,调用的是unlocked_ioctl,如果是32位的APP运行在32位的kernel上,调用的也是unlocked_ioctl

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

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

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

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

int (*flush) (struct file *, fl_owner_t id);

对flush操作的调用发生在进程关闭设备文件描述符的时候,它应该执行(并等待)设备上尚未完结的操作。请不要将它同用户程序使用的fsync操作相混淆。目前,flush仅仅用于少数几个驱动程序,比如SCSI磁带驱动程序用它来确保设备被关闭之前所有的数据都被写入磁带中。如果flush被置为NULL,内核将简单地忽略用户应用程序的请求。

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

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

注意:release并不是在进程每次调用close时都会被调用。只要file结构被共享(如在fork或dup调用之后),release就会等到所有的副本都关闭之后才会得到调动。如果需要在关闭任意一个副本时刷新那些待处理的数据,则实现flush方法。

int (*fsync) (struct file *, loff_t, loff_t, int datasync);

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

int (*fasync) (int, struct file *, int);

这个操作用来通知设备起FASYNC标志位发生了变化。如果设备不支持异步通知,该字段可以是NULL。

int (*lock) (struct file *, int, struct file_lock *);

lock方法用于实现文件锁定,锁定是常规文件不可缺少的特性,但设备驱动程序几乎从来不会实现这个方法。

ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

由内核调用,将数据发送到对应的文件,每次一个数据页。设备驱动程序通常也不需要实现sendpage。

unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

该方法的目的是在进程的地址空间中找到一个合适的位置,以便将底层驱动设备中的内存段映射到该位置。该任务通常由内存管理代码完成,但该方法的存在可允许驱动程序强制满足特定设备需要的任何对齐需求。大部分驱动程序可设置该方法为NULL。

int (*check_flags)(int);

该方法允许模块检查传递给fcntl(F_SETFL...)调用的标志。

...

file_operations相关推荐

  1. linux 内核 file_operations结构体各项解析

    struct module *owner 第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模块被卸载. 几 ...

  2. linux 内核 struct file_operations中 ioctl 变为 unlocked_ioctl

    1.消失的确切时间     ioctl的消失到底是从哪个版本开始的?网上给出的时间是2.6.36开始.网上就是这么说,但是自己必须找到代码中的证据.于是我通过git搜索主线内核代码,找到的删除ioct ...

  3. linux 内核 数据结构 file_operations、file、inode

    文件操作结构 将驱动程序操作连接到设备编号,结构定义在<linux/fs.h>,其中包含一组函数指针,每个打开的文件(在内部由一个file结构表示)和一组函数关联(通过包含指向一个file ...

  4. Linux驱动程序中的file,inode,file_operations三大结构体

    本文允许转载,但请标明出处:http://blog.csdn.net/u010944778/article/details/45077565 file_operations:     该结构是将系统调 ...

  5. file_operations结构

    Linux中字符设备驱动程序的主要功能是实现设备的读写和控制接口.对于字符设备驱动程序,最核心的就是file_operations结构,这个结构实际上是VFS(虚拟文件系统)的文件接口,它的每一个成员 ...

  6. 【驱动】使用结构体 file_operations封装驱动设备的操作 | 结构体初始化

    -----第一部分----- 最近学习到了Linux驱动章节的课程,对设备的对应驱动的注册有些困惑,看了下发现是把设备的所有操作方法封装到结构体 file_operations 中,这个结构体为所有的 ...

  7. Linux 字符设备驱动结构(四)—— file_operations 结构体知识解析

    前面在 Linux 字符设备驱动开发基础 (三)-- 字符设备驱动结构(中) ,我们已经介绍了两种重要的数据结构 struct inode{...}与 struct file{...} ,下面来介绍另 ...

  8. file_operations结构体分析 (设备文件的操作)

    linux设备驱动中file_operations结构体分析  struct module *owner 第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块 ...

  9. file_operations结构体介绍

    内核中file_operations源码 linux-2.6.22.6 /include/linux/fs.h 具体内容在最后 //code from : linux2.6.22.6 /** NOTE ...

  10. 驱动注册的两种方式(一)——file_operations结构体

    使用file_operations结构体进行字符驱动设备的注册/注销: #include <linux/module.h> //module_init() & module_exi ...

最新文章

  1. 通往大神之路,百度Java面试题前200页。
  2. JeecgBoot 2.x版本SQL漏洞补丁发布——响应零日漏洞修复计划
  3. mybatis如何在控制台打印执行的sql语句
  4. java 枚举 注解_Java枚举类和注解梳理
  5. dom4j读取配置文件
  6. 一文读懂hosts文件
  7. vue.js中使用甘特图(gantt-elastic)的使用
  8. 可编辑div在光标位置插入指定内容
  9. 电脑桌面计算机找不到,电脑桌面没有了怎么恢复?电脑桌面没有了的恢复方法...
  10. 数据结构上机实验6.29
  11. 11.2. Yate Client
  12. 学习经验分享【26】论文写作画图方法(持续更新)
  13. Python深度学习与机器视觉(一)
  14. 学术大咖教你一个轻松在论文中画出漂亮插图的方法
  15. tensorflow 1.14 ssd_mobilenet_v1 模型训练
  16. File “pycocotools/_mask.pyx“, line 292, in pycocotools._mask.frPyObjects IndexError: list index ..
  17. JZ2440恢复出产设置
  18. Ubuntu 搭建小熊派 hi3861 环境
  19. 【Unity3D】材质 Material ( 材质简介 | 创建材质 | 设置材质属性 | 对 3D 物体应用材质 | 资源拖动到 Inspector 检查器中的 Material 属性中 )
  20. 下班后两小时,决定你将会成为怎样的人—— 时间管理篇

热门文章

  1. python之word文档生成
  2. 大数据分布式数据处理系统,主要分为哪两种?
  3. 阔别课堂六年,懵懂少年站在新起点
  4. Spring 自带缓存Spring Cache
  5. matlab符号运算实验目的,MATLAB符号计算实验报告.doc
  6. 【NLP学习笔记】停用词(stop words)
  7. ios中域名转换为ip地址
  8. charles手机安装证书
  9. Stata绘图:世行可视化案例-条形图-密度函数图-地图-断点回归图-散点图
  10. 语义分割MIoU代码解析