Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Invalid parameters" error when trying to insert module that accesses exported symbol

I'm trying to share a global variable between two modules in order to understand how to use the EXPORT_SYMBOL macro correctly, but I keep getting an Invalid paramaters error when I try to insert the second module.

In the first module foo.c:

#include <linux/module.h>
#include <linux/kernel.h>

extern unsigned myvar;
unsigned myvar = 42;
EXPORT_SYMBOL(myvar);

static int __init foo_init(void){
        printk(KERN_INFO "HELLO FROM MODULE 1");

        return 0;
}

static void __exit foo_exit(void){
        printk(KERN_INFO "BYE FROM MODULE 1");
}

module_init(foo_init);
module_exit(foo_exit);

MODULE_LICENSE("GPL");

In the second module bar.c:

#include <linux/module.h>
#include <linux/kernel.h>

extern unsigned myvar;

static int __init bar_init(void){
        printk(KERN_INFO "HELLO FROM MODULE 2");

        printk(KERN_INFO "myvar: %u", myvar);

        return 0;
}

static void __exit bar_exit(void){
        printk(KERN_INFO "BYE FROM MODULE 2");
}

module_init(bar_init);
module_exit(bar_exit);

MODULE_LICENSE("GPL");

I compile each module in separate directories with separate Makefiles. Then I insert each module manually:

# insmod foo.ko
# insmod bar.ko

Error: could not insert module bar.ko: Invalid parameters   

If I attempt to insert bar.ko first, I receive the expected unknown symbol error:

# insmod bar.ko
Error: could not insert module bar.ko: Unknown symbol in module

Here's the symbol dump:

# nm foo.ko | grep myvar

00000000ec933bae A __crc_myvar
0000000000001118 r __kcrctab_myvar
000000000000057c r __kstrtab_myvar
0000000000000b20 r __ksymtab_myvar
0000000000000180 D myvar

I'm running a Debian system (kernel v3.2.21) with a Xenomai patch applied:

# uname -r
3.2.21-xenomai-2.6.2.1-ipipe

Unfortunately, I don't think CONFIG_KALLSYMS_ALL is enabled, so I can't look in /proc/kallsyms/ to verify that myvar is actually exported.

like image 548
Vilhelm Gray Avatar asked May 03 '13 13:05

Vilhelm Gray


1 Answers

I decided to poke around the system to try to find the cause of the error:

# dmesg | tail
[11169.107152] HELLO FROM MODULE 1
[11226.101245] bar: no symbol version for myvar
[11226.101254] bar: Unknown symbol myvar (err -22)

Looks like the problem wasn't with exporting the symbol, but rather accounting for the symbol version.

The solution is detailed in Documentation/kbuild/modules.txt and is quite simple: make sure the symbol has an entry in the Module.symvers file.


For example, in my case the two modules where located in /home/vilhelm/foo/ and /home/vilhelm/bar/ respectively. Since I compile each module separately, each directory has its own respective Makefile. First I executed make in the foo directory to generate the Module.symvers file in that directory for the foo module.

# make

Next I modified the Makefile for the bar module by inserting the following line at the top of the Makefile:

KBUILD_EXTRA_SYMBOLS := /home/vilhelm/foo/Module.symvers

Note that this is an absolute path!

Finally I execute make in the bar directory and insert the module manually:

# make

...

# insmod /home/vilhelm/foo/foo.ko
# insmod /home/vilhelm/bar/bar.ko

No errors, so that's a good sign.

And now the moment of truth:

# dmesg | tail
[12675.200451] HELLO FROM MODULE 1
[12715.743320] HELLO FROM MODULE 2
[12715.743328] myvar: 42

Success! :-)

like image 165
Vilhelm Gray Avatar answered Oct 25 '22 22:10

Vilhelm Gray