我正在尝试读取我正在工作的模块的配置文件(在内核中的特定位置找到/生成)。
我可以通过使用带有O_RDONLY标志的filp_open来读取整个文件(只读),但我想不出一种逐行读取它的方法。
当前代码
f = filp_open("/etc/my_module",O_RDONLY, 0);
if ( f==NULL) {
printk("Error in loading config for birdge.\n");
return 1;
} else {
fs = get_fs();
set_fs(get_ds());
/* read line config here */
f->f_op->read(f, buf, 128, &f->f_pos);
set_fs(fs);
printk("buf:%s\n",buf);
}
Linux内核版本:3.8.0-29-generic
我想要实现的是将每个(第n)行放入缓冲区数组(char * buf [128] [128]),然后我将使用pure c将参数和值分块。
通过这种方式,配置文件中的变量可以在模块的运行时使用,当然我会做一些条件检查配置是否正常。
由于
答案 0 :(得分:4)
解析内核中的配置文件很麻烦且很危险。别这么做。
如果您的内核模块需要配置,通常通过在加载模块时传递参数来完成,例如: insmod example.ko foo=123
。您可以使用module_param
宏在模块中声明这些参数。有关如何执行此操作的信息,请参阅the Linux Kernel Module Programming Guide。
如果您的模块需要比使用模块参数更复杂的配置,则模块可能适合在sysfs中为此配置创建端点。请注意,这将意味着您的模块很可能需要一个用户空间帮助程序脚本来配置它。 这是正常的,没问题。在用户空间中编写此脚本将比在内核中运行更简单,更安全。
答案 1 :(得分:2)
[TL; DR:避免直接从内核空间读取文件系统文件。]
你差不多完成了。
您目前唯一需要的是使用kcalloc()
分配一个字符串数组(类似于libc calloc()
,并附加一个参数,您可以将[为了示例]设置为GFP_KERNEL ),然后使用f->f_op->read(f, &chr, 1, &f->f_pos);
循环遍历文件(通过char读取char,类似于libc read(f, &chr, 1)
...稍后您可以通过读取块中的文件并处理块来避免大量的读取内核空间。)
这将为您提供与内核域fgetc()
类似的方法,以及与calloc()
数组的char *buf[]
类似的接口。
您还可以实现自己的(优化不佳)kfgetc()
,例如:
int kfgetc(struct file *f) {
char chr = 0;
f->f_op->read(f, &chr, 1, &f->f_pos);
return chr;
}
通过此示例,您可以轻松创建kfgets()
(仅使用kfgetc()
循环,直到找到'\ n'或者没有其他内容可供阅读。
请注意,一般来说,你所做的事情似乎并不是一个好习惯(说实话,这是一个非常糟糕的主意),但把它放在一边(因为我不知道你为什么这么做)这样做,以上是一个良好的开端,让它工作。当它开始工作时,看看你可以优化它的位置(也可以看看其他内核组件如何检索配置,如@ZanLynx所述)。
针对您的案例的其他一些有用的内存分配器(如果您不知道文件中有多少行,kcalloc()
可能无法解决您的问题):kmalloc()
和krealloc()
(类似于libc malloc()
和realloc()
)。