mav*_*989 1 driver linux-device-driver
我试图弄清楚驱动程序中的文件操作是如何工作的.我知道有几个文件操作,但这些操作的函数是用几个参数调用的,而操作本身是在没有任何参数的情况下定义的.
所以,如果我有这个 -
static const struct file_operations proc_myled_operations = {
.open = proc_myled_open,
.read = seq_read,
.write = proc_myled_write,
.llseek = seq_lseek,
.release = single_release
};
Run Code Online (Sandbox Code Playgroud)
现在我知道内核级驱动程序只能作为来自用户应用程序的文件进行访问.这是一个嵌入式系统,所以我有一些LED可以通过写入它们的存储器映射寄存器来打开.
所以.write或"proc_myled_write"调用将在我通过使用fopen打开此文件然后使用fputs打开此文件来执行我可以执行的指令时执行.但是如果.write被映射为"proc_myled_write并且这个函数有这样的参数 -
static ssize_t proc_myled_write(struct file *file, const char __user * buf,
size_t count, loff_t * ppos)
Run Code Online (Sandbox Code Playgroud)
争论会怎样?使用这些参数没有函数调用上述函数.我在几个司机中看过这个.我刚用过这个,因为这是一个简单的例子.文件操作如何映射到这些函数?例如,用户空间中的"写入"如何跟踪驱动程序中的写入?
谢谢.
当你说"没有用这些参数调用上述函数的函数时"时,我并不完全确定你的意思.
原型为完成这些功能的定义声明struct file_operations本身.
以下是struct声明的前几行:
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
...
Run Code Online (Sandbox Code Playgroud)
虽然参数未在声明中命名,但您可以清楚地看到write()函数声明了4个参数,这些参数与您在问题中提到的类型相匹配.
将函数分配给其相应的字段(proc_myled_operations.write = proc_myled_write)时,只需将指针传递给模块中声明和定义的write函数.函数指针本身不需要参数.
好的,所以你真正的问题是:"用户空间系统调用最终如何调用模块中的写入功能?" 好问题!我建议编辑你的问题,以便为将来的读者提供更清晰的信息.
那么,让我们看看我是否可以按照文章记录.我发现这个文档给了我查看write()系统调用代码的起始位置.它非常古老,但是,嘿,内核中的一切都没有变化!我们write()在fs/read_write.c中的系统调用声明开始我们的旅程:
SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
size_t, count)
Run Code Online (Sandbox Code Playgroud)
它使用文件描述符fd来获取struct file您在注册字符驱动程序时创建的内容.然后它获取文件中的当前位置并调用vfs_write().
ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
Run Code Online (Sandbox Code Playgroud)
它在这个函数中看到以下行:
ret = file->f_op->write(file, buf, count, pos);
Run Code Online (Sandbox Code Playgroud)
它就是!
为了减轻对类型的疑虑file->f_op,我们来看看该定义,struct file并看到该f_op字段的以下定义:
const struct file_operations *f_op;
Run Code Online (Sandbox Code Playgroud)
因此struct file_operations,当您注册驱动程序时,必须是您传入的内容.唷!
希望所有这些链接都会向您展示如果您感到好奇,如何跟踪其他系统调用的跟踪.