linux 驱动开发,file_operations 结构体

在 Linux 驱动开发中,struct file_operations 是字符设备驱动的核心接口,定义了驱动支持的所有文件操作(如 open/read/write)。它是驱动与用户空间交互的桥梁,每个函数对应一个系统调用。


1. 结构体定义

定义在 <linux/fs.h> 中,核心成员如下:

struct file_operations {
    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);
    // 其他成员(如 poll、mmap 等)
};

2. 关键成员函数

(1) open 和 release
  • open:首次打开设备时调用,用于初始化硬件或分配资源。

    static int my_open(struct inode *inode, struct file *file) {
        // 获取设备私有数据(如硬件寄存器地址)
        struct my_device *dev = container_of(inode->i_cdev, struct my_device, cdev);
        file->private_data = dev;
        // 初始化硬件...
        return 0;
    }
  • release:文件关闭时调用,释放资源。

    static int my_release(struct inode *inode, struct file *file) {
        struct my_device *dev = file->private_data;
        // 关闭硬件...
        return 0;
    }
(2) read 和 write
  • read:从设备读取数据到用户空间。

    static ssize_t my_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
        struct my_device *dev = file->private_data;
        // 从硬件读取数据到内核缓冲区
        copy_to_user(buf, dev->kernel_buffer, count); // 复制到用户空间
        return count;
    }
  • write:将用户空间数据写入设备。

    static ssize_t my_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
        struct my_device *dev = file->private_data;
        copy_from_user(dev->kernel_buffer, buf, count); // 从用户空间复制
        // 写入硬件...
        return count;
    }
(3) unlocked_ioctl
  • 处理设备特定的控制命令(如配置寄存器)。

    static long my_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
        struct my_device *dev = file->private_data;
        switch (cmd) {
        case MY_IOCTL_CMD:
            // 处理命令...
            return 0;
        default:
            return -EINVAL;
        }
    }

3. 驱动中的使用示例

// 1. 定义 file_operations 实例
static const struct file_operations my_fops = {
    .owner = THIS_MODULE,
    .open = my_open,
    .release = my_release,
    .read = my_read,
    .write = my_write,
    .unlocked_ioctl = my_ioctl,
};

// 2. 注册字符设备
static int __init my_init(void) {
    dev_t dev = MKDEV(major, 0);
    cdev_init(&my_cdev, &my_fops);
    return cdev_add(&my_cdev, dev, 1);
}

4. 关键注意事项

  1. 线程安全

    • 使用互斥锁(如 mutex_lock)保护共享资源:

      static DEFINE_MUTEX(my_mutex);
      static int my_open(...) {
          mutex_lock(&my_mutex);
          // 初始化操作...
          mutex_unlock(&my_mutex);
          return 0;
      }
  2. 用户空间交互

    • 使用 copy_to_user/copy_from_user 安全访问用户内存。
    • 返回负数错误码(如 -EFAULT 表示内存错误)。
  3. 权限检查

    if (!capable(CAP_SYS_ADMIN))
        return -EPERM; // 拒绝非特权用户访问
  4. 偏移量管理

    • 通过 loff_t *ppos 跟踪文件读写位置(如支持 lseek)。

5. 高级主题

  • 异步 I/O:实现 .aio_read/.aio_write 支持异步操作。
  • 轮询/select:实现 .poll 函数通知文件就绪状态。
  • 内存映射:通过 .mmap 将设备内存映射到用户空间。

总结

struct file_operations 是驱动与用户空间的接口契约。通过填充此结构体,驱动开发者将硬件操作映射到标准文件操作,使得用户空间程序可以通过 open()/read()/write() 等系统调用与设备交互。正确实现这些函数是编写稳定字符设备驱动的关键。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值