驱动程序中的文件操作和结构声明

File operation in drivers and struct declaration

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

我有以下结构:

    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

这是link中的特定行:

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

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

这里提出并回答了一个类似的问题,但我觉得我的问题被遗漏了: File operations in drivers

谢谢

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

结构或联合类型的成员不能有函数类型,但它们可以有指向函数的指针类型。例如,在Linux内核中,struct file_operationsopen成员需要声明为指向函数类型的指针:int (*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_opendev_readdev_writedev_release 函数指示符 用作 赋值表达式来初始化fops的成员。函数指示符是具有 function 类型的表达式。除非它是 sizeof_Alignof 或一元运算符 & 的操作数,否则函数指示符将转换为 指向函数 类型的指针。因此,上面定义的变量foo正好等价于:

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

(别忘了还要初始化 .owner = THIS_MODULE,。)

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

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