File io Linux内核模块中的文件I/O
我正在编写一个需要打开和读取文件的Linux内核模块。实现这一点的最佳方法是什么?假设您可以获得指向相关函数的指针指向打开的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)
/读取的/关闭的系统调用,您可以执行以下操作:
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中的文件读取的机制,所以我可能不需要直接读取文件。的可能重复