Question

All

I'm developing a module in Fedora14 with linux kernel 2.6.35. The OS is running in virtual box actually.

What I observed is that after I made some changes to my code and hit a taint kernel warning, the printk won't work any more, even if I revert the code to previous version. And then if I just copy the previous code to create another module with different name, it will work again... I'm not sure if it is a bug or not, but it is reproducible.

Following is the basic code which is working well. I can see the printk messages in /var/log/messages

sniffer.c

#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);

Makefile

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

Then I made the changes, which is just a test for a multi-file module

sniffer.c

#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);

Makefile

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

proto_handler.c

#include <linux/module.h>

void test_handler(void)
{
    printk(KERN_INFO "this is a test");
}

proto_handler.h

void test_handler(void);

Then, after I make and run insmod, I see these messages in /var/log/messages

sniffer: module license 'unspecified' taints kernel

Disabling lock debugging due to kernel taint

Firstly, I don't know why these messages are displayed since I specified my license.

Secondly, after seeing these messages, I can never see the results of printk of this module any more by running insmod or rmmod, even if I revert my code. But as I said, I can just copy the previous code to a module with other name and it will work again. Is there something like blacklist in Linux?

Can anyone help me? Really appreciated!

Was it helpful?

Solution

The problem is with your Makefile, specifically the sniffer-objs := proto_handler.o line.

When you specify object, you must specify all objects that are to be included as part of the ko module object. In addition, it seems that if you have multiple source files, the names of the source files must not match the final object name. ie. sniffer.o represents the final linked object comprising both of the source objects. So, instead of having a sniffer.c and a proto_handler.c, change the name to sniffer_main.c.

With your current makefile, sniffer.o will only contain the contents of proto_handler.o which doesn't include any of the module initialisation or exit code, nor the license details.

Here's a dump of nm sniffer.o with your current makefile, notice the lack of init_module functions and other module related symbols:

0000000000000000 r ____versions
0000000000000009 r __mod_vermagic5
0000000000000000 r __module_depends
0000000000000000 D __this_module
                 U printk
0000000000000000 T test_handler

Now, with your source files renamed to sniffer_main.c and proto_handler.c, and the following makefile change:

sniffer-objs := sniffer_main.o proto_handler.o

The final sniffer.o object contents now includes all the necessary symbols.

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

You can also get some clues as to what's happening in the make output. With your original Makefile, sniffer.c is never compiled to sniffer.o.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top