File io Linux内核模块中的文件I/O

File io Linux内核模块中的文件I/O,file-io,linux-kernel,kernel-module,File Io,Linux Kernel,Kernel Module,我正在编写一个需要打开和读取文件的Linux内核模块。实现这一点的最佳方法是什么?假设您可以获得指向相关函数的指针指向打开的/读取的/关闭的系统调用,您可以执行以下操作: mm_segment_t fs = get_fs(); set_fs(KERNEL_DS); fd = (*syscall_open)(file, flags, mode); if(fd != -1) { (*syscall_read)(fd, buf, size); (*syscall_close)(fd)

我正在编写一个需要打开和读取文件的Linux内核模块。实现这一点的最佳方法是什么?

假设您可以获得指向相关函数的指针指向打开的
/
读取的
/
关闭的
系统调用,您可以执行以下操作:

mm_segment_t fs = get_fs();
set_fs(KERNEL_DS);

fd = (*syscall_open)(file, flags, mode);
if(fd != -1) {
    (*syscall_read)(fd, buf, size);
    (*syscall_close)(fd);
}
set_fs(fs);

您需要创建我已经展示过的“
syscall”
”函数指针。我确信有更好的方法,但我相信这会起作用。

您也可以在这里找到一些有关sys\u call\u open的信息。

请问您为什么要打开文件

我喜欢关注Linux开发(出于好奇,我不是内核开发人员,我是Java开发人员),我以前也看过关于这个问题的讨论。我能找到一个关于这个的答案,基本上说这通常是个坏主意。我几乎可以肯定LWN在去年报道了这篇文章,但我很难找到这篇文章

如果这是一个私有模块(比如一些定制硬件,该模块不会被分发),那么您可以这样做,但我的印象是,如果您打算将代码提交到主线,那么它可能不会被接受

Evan Teran提到了sysfs,这对我来说似乎是个好主意。如果你真的需要做更难的定制工作,你可以随时制作新的IOCTRL

编辑:


好的,我找到了我要找的那篇文章,它来自。它解释了为什么做这类事情通常是个坏主意,然后继续告诉你到底怎么做。

一般来说,如果你需要从内核模块读/写文件,你在架构上做了一些错误的事情

存在允许内核模块与用户空间助手进程对话的机制(例如netlink,或者只是注册一个字符设备)。用户空间助手进程可以做它想做的任何事情

您还可以实现一个系统调用(或类似的调用),以获取在用户空间中打开的文件描述符,并从内核读取/写入它

这可能比试图在内核空间中打开文件更整洁


还有一些其他东西已经从内核空间打开了文件,您可以查看它们(循环驱动程序浮现在脑海中?)

/proc文件系统也适合私人使用,而且很简单。

所有的内核开发人员都说内核空间的文件I/O不好(特别是当您通过路径引用这些文件时),但主流内核在加载固件时会这样做。如果您只需要读取文件,请使用

kernel_read_file_from_path(const char *path, void **buf, loff_t *size, loff_t max_size, enum kernel_read_file_id id)
函数,即固件加载程序代码使用的函数,在
include/linux/fs.h
中声明。此函数在出错时返回负值

我不太确定最后的
id
变量的意义,如果你看代码,它并没有真正被使用,那么就在那里放一些类似
READING\u FIRMWARE
的东西(没有引号)

buf
不是以null结尾的,而是在
size
中引用其大小。如果需要以null结尾,请创建一个长度为
size+1
字节的字符串,将其复制或重写
kernel\u read\u file()
函数(由
kernel\u read\u file\u from\u path()
使用,在
fs/exec.c
中定义),并将其添加到分配内存的
i\u size
中。(如果要执行此操作,可以使用不同的函数名在模块中重新定义
内核\u read\u file()
函数,以避免修改整个内核。)

如果需要写入文件,有一个
kernel\u write()
函数(类似于
kernel\u read()
,由
kernel\u read\u file()
使用,因此也由
kernel\u read\u file\u from\u path()
使用),但没有
kernel\u write\u file()
kernel\u write\u from\u from\u path()
函数。您可以查看Linux内核源代码树中
fs/exec.c
文件中的代码,其中
kernel\u read\u file()
kernel\u read\u file\u from\u path()
被定义为编写您自己的
kernel\u write\u file()
kernel\u write\u from\u path()
可以包含在模块中的函数


和往常一样,您可以使用此函数将文件内容存储在char指针中,而不是void指针中。

是的,我已经看过了。顺便说一句,我正在修补open(2)系统调用,实际上我需要读取修补版本中的一个文件。它是一个自定义模块,不会分发。我需要打开一个包含inodes=>checksums映射的文件。@mipadi:我找到了我想到的那篇文章,它准确地解释了如何从内核打开和读取文件(在“不要这样做”部分之后)。我编辑了我的帖子来反映这一点,并包含了链接。祝你好运。我实际上已经更改了从/proc中的文件读取的机制,所以我可能不需要直接读取文件。的可能重复