Linux驱动程序中文件操作结构体file_operations中定义的操作函数open、read、write 和 release 等函数都有固定的参数形式和返回值类型,它们何时被调用,各参数意义是?

结构体file_operations的定义和各成员函数的作用

结构体file_operations 的完整定义可参考下面这篇博文:
https://blog.youkuaiyun.com/wenhao_ir/article/details/144905840

因为定义比较长,所以这里只截取部分作为其简单定义,能把问题说明清楚就行。

简单定义如下:

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 *);
    int (*open)(struct inode *, struct file *);
    int (*release)(struct inode *, struct file *);
    long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
    ...
};

从这个定义我们可以看出,file_operations 中最常用的 openreadwriterelease 函数都有固定的参数形式和返回值类型,内核通过这些标准化的接口来调用驱动程序。这些函数的原型是固定的,驱动程序必须遵循这些原型,以便内核能够正确调用并与驱动程序进行交互。

它们的作用和何时被调用的情况分别如下:

  • open:当文件被打开时调用,比如系统内核函数open会调用它。
  • read:当文件被读取时调用,比如系统内核函数read会调用它。
  • write:当数据写入文件时调用,比如系统内核函数write会调用它。
  • release:当文件被关闭时调用,比如系统内核函数close会调用它,典型的语句为close(fd)

各操作函数的参数意义

下面介绍这些函数的固定参数的意义。

下面这几个函数都或多或少的用到了参数inode和file,关于这两个参数的详细介绍,请参考下面这篇博文:
https://blog.youkuaiyun.com/wenhao_ir/article/details/144931005

下面这几个函数都或多或少的用到了参数inode和file,关于这两个参数的详细介绍,请参考下面这篇博文:
https://blog.youkuaiyun.com/wenhao_ir/article/details/144931005

下面这几个函数都或多或少的用到了参数inode和file,关于这两个参数的详细介绍,请参考下面这篇博文:
https://blog.youkuaiyun.com/wenhao_ir/article/details/144931005

所以在下面对各参数的介绍中,就不再对参数inode和file作深入的介绍了。

1. open 操作函数

int (*open) (struct inode *inode, struct file *file);
  • inode:指向文件的 inode 结构体,表示文件的元数据。通过 inode,驱动程序可以获取文件的状态、权限等信息。调用文件操作结构体file_operations中open操作函数时,内核会把系统中的inode实例赋给它。
  • file:指向与打开的文件相关的 struct file 结构体,包含与文件操作相关的状态信息,对于驱动程序,还可以通过它的成员private_data访问和管理文件的私有数据。调用文件操作结构体file_operations中open操作函数时,内核会把系统中的file实例赋给它。

open 成员函数在系统内核的open函数每次打开文件时被调用。你可以在这个函数中初始化一些设备的状态或分配资源。

2. read 操作函数

ssize_t (*read) (struct file *file, char __user *buf, size_t count, loff_t *offset);
  • file:指向与打开的文件相关的 struct file 结构体。包含了文件的私有数据、状态等信息。
  • buf:指向用户空间的缓冲区,内核会将数据从内核空间复制到这个缓冲区。这个参数由系统内核的read函数传递给它,系统内核的read函数的原型为:ssize_t read(int fd, void *buf, size_t count);,这里面的参数void *buf会传递给 read 操作函数的参数char __user *buf
  • count:表示请求读取的数据量。这个参数由系统内核的read函数传递给它,系统内核的read函数的原型为:ssize_t read(int fd, void *buf, size_t count);,这里面的参数size_t count会传递给 read 操作函数的参数size_t count
  • offset:文件或设备的当前偏移量,内核会在每次读取操作时传递给驱动程序,并且在读取后自动更新它。这个量实际上存储在每个文件中struct file实例中的,调用文件操作结构体file_operations中的read操作函数时,系统会把这个量自动赋给它。

值得注意的是,这个函数的返回值类型是ssize_t,它表示从内核空间读取了多少个字节的数据到用户空间。它的返回值也会作为系统内核函数read的返回值。

read 成员函数在每次读取操作时被调用,比如系统内核函数read会调用它,驱动程序需要将数据从内核缓冲区复制到用户缓冲区。

3. write 操作函数

ssize_t (*write) (struct file *file, const char __user *buf, size_t count, loff_t *offset);
  • file:指向与打开的文件相关的 struct file 结构体。
  • buf:指向用户空间的缓冲区,内核会将用户空间的数据从 buf 复制到内核空间。这个参数由系统内核的write函数传递给它,系统内核的write函数的原型为:ssize_t write(int fd, const void *buf, size_t count);,这里面的参数const void *buf会传递给 write 操作函数的参数const char __user *buf,。这里面的const表示缓冲区数据不能被修改,这是为了防止在写入数据的过程中,源数据被意外修改。
  • count:表示请求写入的数据量。这个参数由系统内核的write函数传递给它,系统内核的write函数的原型为:ssize_t write(int fd, const void *buf, size_t count);,这里面的参数size_t count会传递给 write 操作函数的参数size_t count
  • offset:文件或设备的当前偏移量,内核会在每次写入操作时传递给驱动程序,并且在写入后自动更新它。这个量实际上存储在每个文件中struct file实例中的,调用文件操作结构体file_operations中的write操作函数时,系统会把这个量自动赋给它。

值得注意的是,这个函数的返回值类型是ssize_t,它表示写入了多个字节的数据到内核空间。它的返回值也会作为系统内核函数write的返回值。

write 函数在每次写入操作时被调用,比如系统内核函数write会调用它,驱动程序需要将数据从用户缓冲区复制到内核缓冲区或设备。

4. release 操作函数

int (*release) (struct inode *inode, struct file *file);
  • inode:指向文件的 inode 结构体,表示文件的元数据。
  • file:指向与文件相关的 struct file 结构体,包含文件的私有数据和状态信息。

release 函数在文件关闭时被调用,比如系统内核函数close会调用它,典型的语句如close(fd)。驱动程序可以在这里清理资源,例如释放在 open 函数中分配的内存或关闭设备。

总结

是的,file_operations 中的 openreadwriterelease 函数都具有固定的参数形式。这些函数的签名由内核定义,驱动程序必须按照这些签名来实现相应的操作。通过这些函数,内核与设备驱动之间能够进行标准化的交互,保证设备操作的一致性和可管理性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值