21

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

4

6 回答 6

35

请问您为什么要打开文件?

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

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

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

编辑:

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

于 2008-11-09T00:33:24.850 回答
9

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

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

于 2008-11-09T00:07:50.830 回答
3

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

存在允许内核模块与用户空间助手进程对话的机制(例如 netlink - 或只是注册字符设备)。该用户空间助手进程可以为所欲为。

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

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

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

于 2008-11-09T11:44:44.963 回答
3

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

于 2008-11-13T13:55:58.437 回答
3

所有内核开发人员都说来自内核空间的文件 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. 如果您需要它以空值终止,请创建一个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()orkernel_write_file_from_path()函数。您可以查看fs/exec.cLinux 内核源代码树中文件中的代码kernel_read_file(),其中kernel_read_file_from_path()定义了您自己的代码kernel_write_file()kernel_write_file_from_path()可以包含在模块中的函数。

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

于 2018-12-04T23:25:56.273 回答
1

您还可以在此Linux 内核模块编程指南中找到有关 sys_call_open 的一些信息。

于 2008-11-09T00:11:05.363 回答