从 Linux 内核驱动程序写入文件失败
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
static int __init hello_start(void)
{
struct file* my_fd;
my_fd = filp_open ("/tmp/foobar", O_WRONLY | O_APPEND, 0);
if (IS_ERR (my_fd))
{
printk (KERN_ERR "Failed to open file. err: %d.\n", my_fd);
}
else
{
my_fd->f_op->write (my_fd, "some data", 10, &my_fd->f_pos);
}
printk(KERN_INFO "Loading hello module...\n");
return 0;
}
static void __exit hello_end(void)
{
printk(KERN_INFO "hello_end.\n");
}
module_init(hello_start);
module_exit(hello_end);
上面的代码在写入文件时给出错误-14。我在这里做错了什么?
这是 dmesg 输出:
[19551.674999] Write returned: -14.
[19551.675004] Loading hello module...
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
static int __init hello_start(void)
{
struct file* my_fd;
my_fd = filp_open ("/tmp/foobar", O_WRONLY | O_APPEND, 0);
if (IS_ERR (my_fd))
{
printk (KERN_ERR "Failed to open file. err: %d.\n", my_fd);
}
else
{
my_fd->f_op->write (my_fd, "some data", 10, &my_fd->f_pos);
}
printk(KERN_INFO "Loading hello module...\n");
return 0;
}
static void __exit hello_end(void)
{
printk(KERN_INFO "hello_end.\n");
}
module_init(hello_start);
module_exit(hello_end);
the above code is giving error -14 while writing in the file. what am I doing wrong here?
Here is the dmesg
output:
[19551.674999] Write returned: -14.
[19551.675004] Loading hello module...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
struct file_operations
的write
成员(在include/linux/fs.h
中)声明如下:注意
__user
第二个参数上的 code> 标记,告诉您它需要一个用户空间指针。当您像从内核中那样调用它时,您正在传递一个内核空间指针;因此是你的记忆错误。@ShinTakezou 到“acct.c”代码的链接就是您想要查看的内容;特别是,调用
set_fs
来欺骗内核使用自己的数据段作为“用户”数据段。The
write
member ofstruct file_operations
(ininclude/linux/fs.h
) is declared like this:Note the
__user
token on the second argument, which tells you it is expecting a user-space pointer. When you call it like you did from the kernel, you are passing a kernel-space pointer; hence your memory fault.@ShinTakezou's link to the "acct.c" code is what you want to look at; in particular, the calls to
set_fs
to trick the kernel into using its own data segment as the "user" data segment.首先,不要忽略警告:您的
%d
不适合my_fd
。然后,我认为一般来说从内核进行文件 I/O 不是一个好主意,除非在“特殊”情况下。
我尝试过 O_CREAT ,一切都很好,除非文件已经存在。其他一切(特别是
O_WRONLY | O_APPEND
)都没有给我机会。我相信,为了使内核中的文件 I/O 与用户空间中的“一样”,需要了解更多的东西,而且这可能有点棘手(或“危险”)。
但是尝试查看 acct.c 代码。
First, do not ignore warnings: your
%d
is not good formy_fd
.Then, I think in general it is not a good idea to do file I/O from kernel, except in "special" cases.
I've tried with O_CREAT and everything is fine except if the file already exists. Everything else (in particular
O_WRONLY | O_APPEND
) gave me no chance.I believe that in order to make file I/O in kernel "as" in user space requires to know more stuffs, and it is likely a bit tricky (or "dangerous").
However try to look at the acct.c code.