所有
我正在使用Linux内核2.6.35在Fedora14中开发一个模块。操作系统实际上是在虚拟框中运行。
我观察到的是,在对代码进行一些更改并发出污点内核警告之后,即使我将代码恢复到以前的版本,printk仍然无法工作。然后,如果我只是复制前面的代码来创建另一个具有不同名称的模块,它将再次工作......我不确定它是否是一个错误,但它是可重现的。
以下是运行良好的基本代码。我可以在/ var / log / messages
中看到printk消息#include <linux/module.h>
static int __init sniffer_init(void)
{
printk(KERN_INFO "sniffer is initializing...");
printk(KERN_INFO "done!\n");
return 0;
}
static void __exit sniffer_exit(void)
{
printk(KERN_INFO "sniffer is cleaning up...");
printk(KERN_INFO "done!\n");
}
MODULE_AUTHOR("xyz");
MODULE_LICENSE("GPL");
module_init(sniffer_init);
module_exit(sniffer_exit);
obj-m += sniffer.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
然后我进行了更改,这只是对多文件模块的测试
#include <linux/module.h>
static int __init sniffer_init(void)
{
printk(KERN_INFO "sniffer is initializing...");
test_handler();
printk(KERN_INFO "done!\n");
return 0;
}
static void __exit sniffer_exit(void)
{
printk(KERN_INFO "sniffer is cleaning up...");
printk(KERN_INFO "done!\n");
}
MODULE_AUTHOR("WEICHAO HUANG");
MODULE_LICENSE("GPL");
module_init(sniffer_init);
module_exit(sniffer_exit);
obj-m += sniffer.o
sniffer-objs := proto_handler.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
#include <linux/module.h>
void test_handler(void)
{
printk(KERN_INFO "this is a test");
}
void test_handler(void);
然后,在我创建并运行insmod之后,我在/ var / log / messages
中看到了这些消息嗅探器:模块许可证'未指定'玷污内核
由于内核污染而禁用锁定调试
首先,我不知道为什么在我指定许可证后显示这些消息。
其次,看到这些消息之后,即使我还原了我的代码,我也无法通过运行insmod或rmmod看到该模块的printk结果。但正如我所说,我可以将以前的代码复制到具有其他名称的模块,它将再次起作用。 Linux中有黑名单吗?
任何人都可以帮助我吗?真的很感激!
答案 0 :(得分:2)
问题在于您的Makefile,特别是sniffer-objs := proto_handler.o
行。
指定对象时,必须指定要作为ko模块对象的一部分包含的所有对象。此外,似乎如果您有多个源文件,源文件的名称必须与最终对象名称不匹配。即。 sniffer.o表示包含两个源对象的最终链接对象。因此,不要使用sniffer.c和proto_handler.c,而是将名称更改为sniffer_main.c。
使用当前的makefile,sniffer.o将只包含proto_handler.o的内容,其中不包含任何模块初始化或退出代码,也不包含许可证详细信息。
这是使用当前makefile转储nm sniffer.o
,注意缺少init_module
函数和其他模块相关符号:
0000000000000000 r ____versions
0000000000000009 r __mod_vermagic5
0000000000000000 r __module_depends
0000000000000000 D __this_module
U printk
0000000000000000 T test_handler
现在,将源文件重命名为sniffer_main.c和proto_handler.c,并更改以下makefile:
sniffer-objs := sniffer_main.o proto_handler.o
最终sniffer.o
对象内容现在包含所有必需的符号。
nm sniffer.o
:
000000000000000 c r __mod_author13
0000000000000000 r __mod_license14
0000000000000000 T cleanup_module
0000000000000000 T init_module
U printk
0000000000000000 t sniffer_exit
0000000000000000 t sniffer_init
0000000000000000 T test_handler
您还可以获得有关make输出中发生的事情的一些线索。使用原始的Makefile,sniffer.c永远不会编译为sniffer.o。