首页 > 解决方案 > 驱动程序中的文件操作和结构声明

问题描述

我试图弄清楚基本内核驱动程序背后的代码是如何工作的。

我有以下结构:

    static struct file_operations fops =
{
   .open = dev_open,
   .read = dev_read,
   .write = dev_write,
   .release = dev_release,
};

我的 dev_open 函数定义为:

static int     dev_open(struct inode *, struct file *);

现在我也熟悉打开设备文件的原型是在 linux/fs.h 中定义的:

http://lxr.linux.no/linux+v3.10/include/linux/fs.h#L1517

这是该链接中的特定行:

int (*open) (struct inode *, struct file *);

现在我的问题是linux/fs.h 中定义的.open = dev_open,和之间的关系是什么?int (*open) (struct inode *, struct file *);是否将 dev_open 的地址传递给int (*open)linux/fs.h 中定义的函数指针?必须有某种关系,或者将 struct fops 定义为“文件操作”类型有什么意义?

在这里提出并回答了一个类似的问题,但我觉得我的问题被遗漏了: 驱动程序中的文件操作

谢谢

标签: driverlinux-device-driverkernel-module

解决方案


我认为这个问题更多是关于 C 而不是 Linux 内核。

结构或联合类型的成员不能具有函数类型,但它们可以具有指向函数类型的指针。例如,在 Linux 内核中,需要使用指向函数类型的指针来声明 的open成员: . 将成员声明为错误。struct file_operationsint (*open)(struct inode *, struct file *);int open(struct inode *, struct file *);

在 Linux 内核代码中的这个变量定义中:

static struct file_operations fops =
{
   .open = dev_open,
   .read = dev_read,
   .write = dev_write,
   .release = dev_release,
};

顺便说一句,上面通常应该owner像这样初始化成员:

   .owner = THIS_MODULE,

表达式dev_open,和是函数指示符dev_read,用作赋值表达式来初始化 的成员。函数指示符是具有函数类型的表达式。除非它是 , 的操作数或一元运算符,否则函数指示符将转换为指向函数类型的指针。因此,上述变量的定义完全等价于:dev_writedev_releasefopssizeof_Alignof&foo

static struct file_operations fops =
{
   .open = &dev_open,
   .read = &dev_read,
   .write = &dev_write,
   .release = &dev_release,
};

(不要忘记也初始化.owner = THIS_MODULE,。)

在那里,函数指示符一元运算&符的操作数,因此不会隐式转换为指向函数类型的指针,但&运算符会将它们显式转换为指向函数类型的指针。

在上面的初始化之后fopsrc = fops.open(inode, file);间接调用dev_open(inode, file)并将返回值赋值给rc。有时您可能会看到这是用旧样式编写的:rc = (*fops.open)(inode, file);. 他们都做同样的事情。函数调用运算符的操作数( )实际上始终是指向函数的指针。在 的情况下rc = (*fops.open)(inode, file);fops.open有一个指向函数类型的指针。取消对函数(*fops.open)类型的引用,但由于是函数指示符,因此它在函数调用之前隐式转换回指向函数类型的指针。同样,在直接调用中,是一个函数指示符,因此有一个fops.open(*fops.open)rc = dev_open(inode, file);dev_open函数类型,但在函数调用之前隐式转换为指向函数类型的指针。


推荐阅读