12

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

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 *devscull_setup_cdev 这里进行了初始化。

我很困惑,因为我认为我们可以创建struct scull_dev *dev一个全局变量,然后scull_read其他方法最终将可以访问它,而无需通过使用inodeand的所有传递file

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

谁能提供一些使用这种方法传递数据的实际例子?

4

5 回答 5

10

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

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

于 2013-12-27T23:44:12.333 回答
8

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

于 2011-09-09T08:36:31.933 回答
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;
 }
于 2011-12-16T11:46:08.873 回答
0

我不认为这是一个安全问题。它更像是一种设计选择。如果我没记错的话,线程安全是通过在 scull_dev 中上下信号量来实现的。如果你深入研究代码,你可以看到 open、read、write 都用到了 down_interruptible()。

我猜作者 1) 认为直接访问 scull_dev 看起来不太好 2) 想向我们展示如何使用 private_data。通过将指向 scull_dev 的指针放在指向每个操作的 struct file 中,每个操作都可以在不使用全局变量的情况下访问它。

于 2013-12-27T23:20:01.477 回答
0

scull 驱动用 4 个 Minor 实现,每个 Minor 都有一个单独的 scull_dev,每个 scull_dev 都嵌入了“struct cdev”。现在假设用户从 /dev/scull0 打开了 scull0。在 open() 函数中,您需要指向正确的 scull_dev 结构。scull_dev 结构是动态分配的。

你可以在这里看到完整的实现 https://github.com/mharsch/ldd3-samples/blob/master/scull/main.c#L450

于 2017-04-27T10:22:14.437 回答