Linux 设备驱动中的file_operations

Linux设备驱动开发:file_operations结构体详解与实战指南 在Linux内核开发中,系统调用是用户空间程序与内核交互的桥梁,而设备驱动则是实现硬件控制的核心模块。其基本原理是通过定义一组标准接口,将用户层的open、read、write等操作映射到具体的硬件操作函数。这一机制的技术价值在于实现了设备抽象与统一访问模型,使得应用程序可以像操作普通文件一样操作硬件设备。在应用场景上,无论是字符设备、块设备还是网络设备,都需要通过实现这些接口来完成数据读写、设备控制等功能。本文聚焦于Linux驱动开发的关键结构体file_operations,深入解析其成员函数如read 阅读详情


   Linxu驱动中的设备文件注册的操作方法结构体,也是向用户层提供操作接口的方法体,我的版本为3.1.10


                                            撰写不易,转载需注明出处:http://blog.youkuaiyun.com/jscese/article/details/43408625


原型在 内核源码 /include/linux/fs.h中定义:


struct file_operations {

    struct module *owner;   

//第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为 THIS_MODULE, 一个在 <linux/module.h> 中定义的宏.

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

//llseek 方法用作改变文件中的当前读/写位置, 并且新位置作为(正的)返回值. loff_t 参数是一个"long offset", 并且就算在 32位平台上也至少 64 位宽. 错误由一个负返回值指示. 如果这个函数指针是 NULL, seek 调用会以潜在地无法预知的方式修改 file 结构中的位置计数器( 在"file 结构" 一节中描述).


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

//用来从设备中获取数据. 在这个位置的一个空指针导致 read 系统调用以 -EINVAL("Invalid argument") 失败. 一个非负返回值代表了成功读取的字节数( 返回值是一个 "signed size" 类型, 常常是目标平台本地的整数类型).


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

//发送数据给设备. 如果 NULL, -EINVAL 返回给调用 write 系统调用的程序. 如果非负, 返回值代表成功写的字节数.


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

//初始化一个异步读 -- 可能在函数返回前不结束的读操作. 如果这个方法是 NULL, 所有的操作会由 read 代替进行(同步地).


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

//初始化设备上的一个异步写.


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

//对于设备文件这个成员应当为 NULL; 它用来读取目录, 并且仅对文件系统有用.


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

//poll 方法是 3 个系统调用的后端: 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);

// 2.6.35 之后的版本只有这两个ioctl,少了inode参数,功能不变 表示系统调用提供了发出设备特定命令的方法


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

//mmap 用来请求将设备内存映射到进程的地址空间. 如果这个方法是 NULL, 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 *);

//在文件结构被释放时引用这个操作. 如同 open, release 可以为 NULL.


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

//这个方法是 fsync 系统调用的后端, 用户调用来刷新任何挂着的数据. 如果这个指针是 NULL, 系统调用返回 -EINVAL.


    int (*aio_fsync) (struct kiocb *, int datasync);

//这是 fsync 方法的异步版本.


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

//这个操作用来通知设备它的 FASYNC 标志的改变. 异步通知是一个高级的主题, 在第 6 章中描述. 这个成员可以是NULL 如果驱动不支持异步通知.


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

//lock 方法用来实现文件加锁; 加锁对常规文件是必不可少的特性, 但是设备驱动几乎从不实现它.


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

//sendpage 是 sendfile 的另一半; 它由内核调用来发送数据, 一次一页, 到对应的文件. 设备驱动实际上不实现 sendpage.


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

//这个方法的目的是在进程的地址空间找一个合适的位置来映射在底层设备上的内存段中. 这个任务通常由内存管理代码进行; 这个方法存在为了使驱动能强制特殊设备可能有的任何的对齐请求. 大部分驱动可以置这个方法为 NULL.


    int (*check_flags)(int);

//这个方法允许模块检查传递给 fnctl(F_SETFL...) 调用的标志.


    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);

//用于从管道传输文件数据,目前只用于splice2系统调用;


    int (*setlease)(struct file *, long, struct file_lock **);

// 设置一个打开标志到open的file

    long (*fallocate)(struct file *file, int mode, loff_t offset,
              loff_t len);

//  通过设置mode标志FA_ALLOCATE或FA_DEALLOCATE,表示preallocation and deallocation of preallocated blocks respectively,由sys_fallocate调用。
};



拿上几篇博客中提到过的例子 evdev.c中的 event%d 设备文件的file_operations :

static const struct file_operations evdev_fops = {
	.owner		= THIS_MODULE,
	.read		= evdev_read,
	.write		= evdev_write,
	.poll		= evdev_poll,
	.open		= evdev_open,
	.release	= evdev_release,
	.unlocked_ioctl	= evdev_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= evdev_ioctl_compat,
#endif
	.fasync		= evdev_fasync,
	.flush		= evdev_flush,
	.llseek		= no_llseek,
};





Linux设备驱动开发:file_operations结构体详解与实战 在操作系统与硬件交互的底层,设备驱动扮演着关键角色,它通过定义标准接口实现用户空间与内核空间的安全通信。其核心原理在于虚拟文件系统(VFS)机制,用户程序对设备文件的读写控制等系统调用,最终会由内核转发到驱动注册的具体函数执行。这一机制的技术价值在于提供了统一、安全的设备访问抽象,极大地简化了应用程序开发。其应用场景广泛,从简单的字符设备到复杂的网络、存储控制器均依赖于此。本文聚焦于Linux驱动开发的核心——file_operations结构体,它正是这一通信契约的具体实现,通过详解其成员函数如read、 阅读详情

相关推荐

linux下的inode_operations 和 file_operations结构体

/ 目录相关操作// 创建文件// 创建目录// 删除文件// 创建符号链接// 创建硬链接// 重命名// 设置权限// 其他操作:权限检查、set/get ACL、文件扩展属性等...// ...⚠️ 注意:上面的函数指针列表是简化 & 代表性的,实际内核中的包含更多函数,而且某些函数是可选的,如果文件系统不支持某个功能,可以设为NULL。// 读写操作// 打开和关闭// 文件定位(比如 lseek)// IO控制(ioctl)

shanstellar的博客 1381

【Linux】linux5.6引入struct proc_ops,用以替代struct file_operations在/proc下进行文件操作

该报错是错误码:EPERM,不允许操作。

m0_47088198的博客 3982

基于Linux的PCIe设备驱动开发入门到精通-- 7.2 实现file_operations:open, release, read, write, mmap, ioctl

通过实现。

MHD0815的博客 103

linux中file_operations结构体详解

/** * author:hasen * 参考:《linux设备驱动开发详解》和sunsea1026的优快云博客 * 作用:方便自己参考查阅 */ struct file_operations{ struct module *owner //第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模

android_hasen博客 3732

MDPI期刊投稿全流程解析:从注册到提交的实用指南

本文详细解析了向MDPI期刊投稿的全过程,从注册账号、完善个人资料、上传稿件,到填写作者信息、推荐审稿人及提交附信等关键步骤。指南强调了使用机构邮箱、遵循期刊模板、认真准备Cover Letter等实用技巧,旨在帮助作者高效、规范地完成投稿,避免常见错误,提升稿件处理效率。

weixin_29250403的博客 924

Optisystem软件与Matlab软件的联合数据读取

目录 Matlab软件程序编写 Optisystem软件的连接与设置 数据读取结果 Matlab软件程序编写 利用Matlab软件按照下图编写程序,保存为getdata.m文件。 OutputPort1 =InputPort1; fileID=fopen('OSAdata.txt','wt'); fprintf(fileID,'%f\n',OutputPort1.Sampled.Signal); fclose(fileID); Optisystem软件的连接与设置 (以基于线性插值法

Vivian_Chen_的博客 4853

Linux内核模块开发 第 7 章

Linux内核模块开发 第 7 章 /proc 文件系统

太白断水客 548

Freemarker整合poi导出带有图片的Excel教程

Freemarker整合poi导出带有图片的Excel教程 https://blog.youkuaiyun.com/x541211190/article/details/105675771根据此人博客可完成此功能,但原文中有一处错误需要纠正,当单元格合并时,计算起始单元格有错误。 源代码: /** * 构造合并单元格集合 * * @param createRowIndex: * @param cellRangeAddresses: * @param startIndex: * @param c

weixin_39403349的博客 1002

static struct file_operations结构体介绍(转)

1、 驱动与内核接口层  驱动与内核接口层主要完成驱动模块在Linux内核的注册加载、卸载清除工作。这部分工作分别由初始化和退出函数完成。  ① 初始化函数完成驱动模块加载:static int __init DS18B20_init(void){  ……  register_chrdev(DS18B20_MAJOR,DEVICE_NAME, &DS18B20_fops);//完成设备注册  #i

weixiuc的专栏 8060

Adobe软件非正版弹窗终极解决方案:PS/Ai/PR/AE禁用提示一键清除指南

本文提供了Adobe软件非正版弹窗的终极解决方案,包括PS、Ai、PR、AE等软件的禁用提示一键清除指南。通过专业清理工具和手动修改系统文件的方法,帮助用户彻底解决Adobe弹窗问题,提升使用体验。适用于Windows和Mac系统用户,操作简单高效。

weixin_30872337的博客 5355

思科模拟器汉化教程(附带中文汉化包)

思科模拟器是一种模拟Cisco网络设备的软件工具。它可以模拟Cisco网络设备的所有功能,包括路由器、交换机、防火墙等,并提供了一个可视化的用户界面,让用户可以通过图形化的方式来管理网络设备。思科模拟器因其便捷、易用的特点被广泛应用于网络工程师的实验、测试和培训等方面思科模拟器的功能是强大的,但当我们在使用思科模拟器的时候就会有一些烦恼,由于思科是全球最大的企业级网络设备供应商之一。思科公司的产品和服务被广泛应用于各种领域和行业,所以思科模拟器默认是全英文的,但是在最新版本中是支持中文的。

2302_76908369的博客 4万+

linux下proc文件的读写(部分转载)

in Linux, proc文件系统是一个虚拟文件系统,用户和应用程序可以通过proc文件系统得到当前的一些系统信息,并可以改变一些内核的参数。/proc下的文件是一种特殊文件,不能够像一般文件一样创建删除。下面讨论proc文件的创建、删除与读写。 1.创建目录: struct proc_dir_entry *proc_mkdir(const char *name,

hunanchenxingyu的专栏 3万+

Unity VR 零基础开发之 Pico4 MR

2、弹出弹窗后,点击Android选项,然后再点击Switch Platform按钮切换成安卓平台。3、切换完成后Android选项后面会显示unity图标。

十画的博客 5104

【Linux】【file_operations】设备驱动中的file_operations详解

首先,我们需要定义设备号。// 自定义主设备号// 分配字符设备号// 初始化 cdev 和 file_operations// 注册字符设备// 创建设备类// 创建设备实例return 0;接下来,我们定义结构体,并实现读写函数。// 读取数据int ret;return 0;// 已经到达文件末尾return ret;// 写入数据// 设备打开时的操作return 0;// 设备关闭时的操作return 0;

极客代码 3176

电子纸价签实战:基于SSD1680的墨水屏驱动开发与优化

本文详细介绍了基于SSD1680驱动芯片的电子纸价签开发实战,涵盖硬件连接、驱动框架搭建、核心流程解析及性能优化。重点剖析了初始化配置、波形文件加载、图像数据写入与刷新触发等关键步骤,并提供了功耗优化、显示效果提升及代码健壮性等实用避坑指南,帮助开发者高效实现稳定低功耗的墨水屏驱动。

weixin_28278377的博客 230

使用 Python 爬虫抓取 IMDb 电影信息 - 评分、评论与基本信息抓取教程

本文介绍了如何使用 Python 爬虫技术抓取 IMDb 电影评分、评论和基本信息。我们分别展示了通过IMDb API和两种方法抓取数据,并进行了数据存储、分析与可视化。在未来,我们还可以基于这些数据开发电影推荐系统、情感分析工具等,进一步丰富电影数据的应用场景。通过这些实践,您不仅学会了如何抓取和存储数据,还可以通过这些基础来构建自己的数据分析应用,获取更丰富的电影数据。

2201_76125261的博客 601

linux设备驱动中file_operations结…

linux设备驱动中file_operations结构体分析  struct module *owner 第 一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为 THIS_MODULE, 一个在 中定义的宏. loff_t (*llseek) (stru

为了部落! 637

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

linux设备驱动中file_operations结构体分析

linux设备驱动中file_operations结构体分析  struct module *owner 第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针. 这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为 THIS_MODULE, 一个在 中定义的宏. loff_t (*llseek)

zhuzhiqi11的专栏 535

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Linux设备驱动开发-填充file_operations

file_op的填充

Leo-夜空的博客 354

file_operations详解

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

littlelee111的专栏 9420

Linux字符驱动设备file_operations结构体分析

原文地址:https://www.cnblogs.com/chen-farsight/p/6181341.html struct _file_operations struct_file_operations在kernel/include/fs.h这个文件里面被定义的,如下所示: struct file_operations {   struct module *owner;//拥有该结...

M2嵌入式 932

file_operations中各项解析

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

c-dev 3万+

Linux中的File_operations结构体

Linux中的File_operations结构体 File_operations结构体        file_operation就是把系统调用和驱动程序关联起来的关键数据结构。这个结构的每一个成员都对应着一个系统调用。读取file_operation中相应的函数指针,接着把控制权转交给函数,从而完成了Linux设备驱动程序的工作。     在系统内部,I/O设备的

doublechen_it的专栏 686

Linux设备驱动开发-file_operations结构体day02

day02 file_operations结构体 其成员函数是字符设备驱动与内核虚拟文件系统的接口,是用户空间对Linux进行系统调用最终的落实者,把系统调用和驱动程序关联起来. 注意: __usr是一个宏,其后的指针指向用户空间. (1)读设备 /*读设备*/ ssize_t xxx_read(struct file *filp,char __user *buf,size_t count,lof...

大琪爱吃鱼的博客 333
上一篇: Linux/Android——Input系统之InputReader (七)
下一篇: Linux/Android——Input系统之InputMapper 处理 (八)
南丶烟
博客等级 码龄14年 569粉丝 98原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值