驱动程序中的文件操作和结构声明
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_operations
的open
成员需要声明为指向函数类型的指针: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_open
、dev_read
、dev_write
和 dev_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在函数调用之前输入函数。
我正在尝试弄清楚基本内核驱动程序背后的代码是如何工作的。
我有以下结构:
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_operations
的open
成员需要声明为指向函数类型的指针: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_open
、dev_read
、dev_write
和 dev_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在函数调用之前输入函数。