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

时间:2008-11-08 23:47:05

标签: file-io linux-kernel kernel-module

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

6 个答案:

答案 0 :(得分:31)

我可以问你为什么要打开文件?

我喜欢关注Linux开发(出于好奇,我不是内核开发人员,我做Java),之前我已经看过这个问题的讨论。我能够找到LKML message这个,基本上提到它通常是一个坏主意。我对LWN在过去一年中的报道几乎是肯定的,但我很难找到这篇文章。

如果这是一个私有模块(比如某些自定义硬件而且模块不会被分发),那么你可以这样做,但我的印象是,如果你要将代码提交到主线那么它可能不被接受。

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

编辑:

好的,我找到了我要找的文章,它来自Linux Journal。它解释了为什么做这种东西通常是一个坏主意,然后继续告诉你究竟该怎么做。

答案 1 :(得分:9)

假设您可以获得指向open / read / close系统调用的相关函数指针的指针,您可以执行以下操作:

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_*”函数指针。我相信有更好的方法,但我相信这会有效。

答案 2 :(得分:2)

一般来说,如果你需要从内核模块读取/写入文件,那么你在架构上做错了。

存在机制(例如netlink - 或只注册字符设备)以允许内核模块与用户空间帮助程序进程通信。用户空间帮助程序进程可以做任何想做的事情。

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

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

还有一些其他东西已经从内核空间打开文件,你可以看一下它们(想到循环驱动程序吗?)。

答案 3 :(得分:1)

您还可以在此Linux Kernel Module Programing Guide中找到有关sys_call_open的一些信息。

答案 4 :(得分:1)

/ proc filesystem也适合私人使用,而且很容易 http://www.linuxtopia.org/online_books/Linux_Kernel_Module_Programming_Guide/x773.html

答案 5 :(得分:0)

所有内核开发人员都说内核空间中的文件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_FIRMWARE之类的内容(无引号)

buf不是以Null结尾的,而是在size中引用其大小。如果需要将其终止为null,请创建一个长度为size + 1个字节的字符串,然后将其复制或重写kernel_read_file()函数(由kernel_read_file_from_path()使用,在fs/exec.c中定义),然后在分配内存的i_size中添加一个。 (如果要执行此操作,可以在模块中使用其他函数名称重新定义kernel_read_file()函数,以避免修改整个内核。)

如果需要写入文件,则有一个kernel_write()函数(类似于kernel_read()kernel_read_file()使用了该功能,因此kernel_read_file_from_path()也使用了该功能),但是没有kernel_write_file()kernel_write_file_from_path()函数。您可以在Linux内核源代码树的fs/exec.c文件中查看代码,其中kernel_read_file()kernel_read_file_from_path()被定义为编写自己的kernel_write_file()kernel_write_file_from_path()函数您可以将其包含在模块中。

和往常一样,通过此函数,可以通过强制转换将文件的内容存储在char指针中,而不是void指针中。