在Linux设备驱动程序编程中使用struct inode和struct文件传递数据的原因

时间:2011-09-09 08:17:55

标签: c linux linux-kernel linux-device-driver inode

我正在学习Linux Device Drivers, 3rd edition的第3.5章。本节介绍一种检索我们自己在open函数中struct inode *inode定义的自定义结构的方法:

int scull_open(struct inode *inode, struct file *filp)
{
    struct scull_dev *dev;

    dev = container_of(inode->i_cdev, struct scull_dev, cdev);
    filp->private_data = dev; /* for other methods */

    }
    return 0;          
}

据我了解,在设备打开时,代表设备的struct inode *inode会传递给scull_open。然后,提取自定义结构dev并将其传递给filp->private_data,以便其他方法(例如scull_read)可以使用它:

ssize_t scull_read(struct file *filp, char _ _user *buf, size_t count,
                loff_t *f_pos)
{
    struct scull_dev *dev = filp->private_data; 
    /* other codes that uses *dev   */
}

在我意识到struct scull_dev *dev here初始化过程中我们已经有scull_setup_cdev之前,我觉得这很好。

我很困惑,因为我认为我们可以使struct scull_dev *dev成为一个全局变量,然后scull_read和其他方法最终可以访问它而无需使用inode进行所有传递和file

我的问题是,为什么我们不把它变成一个全局变量?

有人能提供一些使用此方法传递数据的实际例子吗?

5 个答案:

答案 0 :(得分:10)

主要原因是您的驱动程序可以管理多个设备。例如,您可以创建(mknod)多个设备/dev/scull1/dev/scull2/dev/scull3 ...然后每个设备都会有不同的scull_dev关联用它。

使用全局变量,您只能使用一个变量。即使您的驱动程序仅支持一个这样的设备,也没有理由不设计代码未来证据。

答案 1 :(得分:8)

主题安全!如果两个线程/进程同时使用驱动程序怎么办?

答案 2 :(得分:0)

您还可以避免使用私人数据来存储您的实际设备,如果您需要私有数据用于不同的设置,这是一种常见的选择。在这种情况下,您需要在scull_read例程中检索次要编号。它会是这样的:

ssize_t scull_read( struct file *filp,
                     char __user* buf,
                     size_t count,
                    loff_t * f_pos ) {

    int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
    printk( "reading on minor number %d\n", minor);
    /* use dev[minor] in ur code */
    return 0;
 }

答案 3 :(得分:0)

我不认为这是一个安全问题。它更像是一种设计选择。如果我没有弄错的话,通过scull_dev中的信号量向下和向上来实现线程安全性。如果深入研究代码,可以看到打开,读取,写入所有使用过的down_interruptible()。

我猜作者1)认为直接访问scull_dev并不好看2)想告诉我们如何使用private_data。通过将scull_dev指向结构文件,其指针被发送到每个操作,每个操作都可以在不使用全局变量的情况下访问它。

答案 4 :(得分:0)

scull驱动程序由4个未成年人实现,每个未成年人都有一个单独的scull_dev,每个scull_dev都有" struct cdev"嵌入其中。现在让我们说User已经从/ dev / scull0打开了scull0。在open()函数中,您需要指向正确的scull_dev结构。 scull_dev结构是动态分配的。

您可以在此处查看完整实施 https://github.com/mharsch/ldd3-samples/blob/master/scull/main.c#L450