Linux 设备驱动系列(六)——文件操作
关注微信公众号:Linux 内核拾遗
1 cdev 结构和文件操作
当需要对设备执行打开/关闭和读写操作时,我们需要在设备驱动程序中注册一些结构,主要是 struct cdev 和文件操作 struct file_operations。
1.1 cdev 结构
Linux 内核中,struct inode 用来表示具体的文件,它包含了文件的大量信息;而 struct file 表示一个打开的文件描述符。一个文件可能有多个 struc file 表示打开的文件描述符,但它们都指向一个相同的 struct inode 结构。
struct cdev 是 inode 结构其中的一个元素,它是 Linux 内核的一个内部结构体,用于表示字符设备。
设备驱动程序需要设置 file_operations 和 owner(通常是 THIS_MODULE 宏)两个字段。
有两种分配和初始化 cdev 结构的方式:runtime allocation 和 own allocation。
1.1.1 Runtime Allocation
可以通过下面的方式在运行时获取一个单独的 cdev 结构:
1.1.2 Own Allocation
可以将 cdev 结构体嵌入到一个设备特定的结构中,然后通过下面的方法进行初始化:
当 cdev 结构体设置好 file_operations 和 owner 后,可以通过下面的方法来通知给内核:
一旦 cdev_add()成功调用,相应的设备就能立即可用,并且 file_operations 中定义的所有函数都能够被调用。
最后可以通过下面方法释放 cdev 结构体:
1.2 文件操作
"linux/fs.h"头文件中定义的 file_operations 结构体,它是注册到设备驱动中字符设备的打开/关闭和读写等操作的回调函数。
它包含了一系列的函数指针,每个打开的文件都会通过 file_operations 关联到对应的操作处理函数集合。这些操作通常是作为系统调用的实现,例如 open、read、write 等等。
值得注意的是,file_operations 中包含了 struct module *owner 字段,它不是函数指针,而是”拥有“该结构体的模块指针,通常设置为"linux/module.h"中定义宏 THIS_MODULE。它用于防止 file_operations 还在使用的时候对应的内核模块被意外卸载。
一般情况下不需要设置所有的函数指针:
1.2.1 read
用于从设备中获取数据,非负数返回值表示成功读取的字节数。
1.2.2 write
用于往设备发送数据,非负数返回值表示成功写入的字节数。
1.2.3 ioctl
ioctl 系统调用提供了一种发送设备特定命令的方式,例如格式化磁盘,它既不是读也不是写操作。
1.2.4 open
打开设备文件的时候会调用 open 函数。
1.2.5 release (close)
struct file 被释放的时候会调用 release 函数。
2 文件操作示例
下面是一个简单的设备文件操作的示例:
file_ops.c
编译运行如下:
关注微信公众号:Linux 内核拾遗
版权声明: 本文为 InfoQ 作者【Linux内核拾遗】的原创文章。
原文链接:【http://xie.infoq.cn/article/d33d60229eac148d6ce68200a】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论