内核模块未加载(但insmod返回0) [英] kernel module in not loaded (but insmod returns 0)
问题描述
我必须向现有设备(mips arch)添加一些功能-我已经尝试了多个SDK,目前我已经取得了一些进步,但是: insmod返回0(成功),而lsmod显示它们,但是printk或create_proc_entry都不起作用....但是我已经查看了.gnu.linkonce.this_module部分:除了模块名称-没有有用的信息-该部分已填充带有0x0的
I've to add some functionality to an existing device (mips arch) - I've tryed several SDK's and at this moment I have some progress, but: insmod returns 0(success) and lsmod shows them, but aither printk nor create_proc_entry doesn't work .... BUT I've viewed section .gnu.linkonce.this_module: except module name - there is no usefull info - section is filled with 0x0's
我发现,在本地.ko文件中,.gnu.linkonce.this_module节的设备大小较小,只有8个字节-但根据该节用于将信息临时加载到struct模块的事实,没有在我看来很重要...
I've found that in native .ko files in device size of section .gnu.linkonce.this_module is smaller into 8 bytes - but according to the fact that section is used for temporary loading info to struct module - there is not matter in my oppinion ...
https://ufile.io/eco1s 有几个文件:khelloworld.ko-我的helloworld模块-尝试创建procfs条目khelloworld.ko-尝试在rootfs(/tmp/test.file)本机模块中创建文件:xt_mark.ko md5.ko cbc.ko
https://ufile.io/eco1s there are several files: khelloworld.ko - my helloworld module - try to create procfs entry khelloworld.ko - try to create file in rootfs (/tmp/test.file) native modules: xt_mark.ko md5.ko cbc.ko
我没有内核配置-但是我需要编译该模块...我只知道版本
I don't have kernel configuration - but I need to compile that module... I know only the version
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
#include <linux/init.h> /* Needed for the macros */
#define procfs_name "khelloworld"
MODULE_LICENSE("GPL");
MODULE_INFO(vermagic, "2.6.32.68 mod_unload MIPS32_R2 32BIT ");
MODULE_AUTHOR ("XAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
struct proc_dir_entry *Our_Proc_File;
static int
procfile_read(char *buffer,
char **buffer_location,
off_t offset, int buffer_length, int *eof, void *data);
static int __init khelloworld_init( void ) {
printk(KERN_INFO "try to create /proc \n");
Our_Proc_File = create_proc_entry(procfs_name, 0644, NULL);
if (Our_Proc_File == NULL) {
remove_proc_entry(procfs_name, NULL);
printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
procfs_name);
return -ENOMEM;
}
Our_Proc_File->read_proc = procfile_read;
Our_Proc_File->owner = THIS_MODULE;
Our_Proc_File->mode = S_IFREG | S_IRUGO;
Our_Proc_File->uid = 0;
Our_Proc_File->gid = 0;
Our_Proc_File->size = 37;
printk(KERN_INFO "/proc/%s created\n", procfs_name);
return 3; /* everything is ok */
}
static void __exit khelloworld_exit( void ) {
remove_proc_entry(procfs_name, NULL);
printk(KERN_INFO "/proc/%s removed\n", procfs_name);
}
module_init(khelloworld_init);
module_exit(khelloworld_exit);
int
procfile_read(char *buffer,
char **buffer_location,
off_t offset, int buffer_length, int *eof, void *data)
{
int ret;
printk(KERN_INFO "procfile_read (/proc/%s) called\n", procfs_name);
/*
* We give all of our information in one go, so if the
* user asks us if we have more information the
* answer should always be no.
*
* This is important because the standard read
* function from the library would continue to issue
* the read system call until the kernel replies
* that it has no more information, or until its
* buffer is filled.
*/
if (offset > 0) {
/* we have finished to read, return 0 */
ret = 0;
} else {
/* fill the buffer, return the buffer size */
ret = sprintf(buffer, "HelloWorld!\n");
}
return ret;
}
推荐答案
readelf -a
表明,您的init函数的重定位条目与本机模块的情况不同:
readelf -a
shows that the relocation entry for your init function is different than in the native module case:
xt_mark.ko
Relocation section '.rel.gnu.linkonce.this_module' at offset 0x958 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
000000bc 00001502 R_MIPS_32 00000000 init_module
00000130 00001402 R_MIPS_32 00000000 cleanup_module
khelloworld.ko
Relocation section '.rel.gnu.linkonce.this_module' at offset 0xafc contains 2 entries:
Offset Info Type Sym.Value Sym. Name
000000ac 00002502 R_MIPS_32 00000000 init_module
0000010c 00002402 R_MIPS_32 00000000 cleanup_module
请注意,对于本机模块,init_module
指针如何位于module
结构的偏移量0xbc中,而在您的模块中,指针如何位于偏移量0xac中.结果,加载程序找不到您的init函数,也不会调用它.
Note how for the native modules, the init_module
pointer is in offset 0xbc of the module
struct, whereas in your module it is in offset 0xac. As a result, the loader does not find your init function and does not call it.
如此处所述,这可能是由于您的构建环境与本机构建环境之间的内核配置不同而导致的.罪魁祸首很可能是CONFIG_UNUSED_SYMBOLS
(请参阅module
定义
As explained here, this is likely the result of a kernel configuration difference between your build environment and the native build environment. It's very likely that CONFIG_UNUSED_SYMBOLS
is the culprit (see the module
definition here).
或者,您可以(后果自负!)对生成的模块应用二进制补丁,以将0xac更改为0xbc.
Alternatively, you can (at your own risk!) apply a binary patch to your resulting module to change the 0xac to 0xbc.
这篇关于内核模块未加载(但insmod返回0)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!