1. Usage of export_symbol in Linux
The functions defined within the Export_symbol tag are exposed to all kernel code and can be called directly into your kernel module without modifying the kernel code. You can also manually modify the kernel source code to export additional functions that are used to recompile and load the new kernel after the test.
mod1.c
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h>module_license ("DUAL BSD/GPL "), int func1 (void) { printk (" in Func:%s.../n ", __func__); return 0;} static int __init hello_init (void) { printk ("Module 1,init!/n"); return 0;} static void __exit hello_exit (void) { printk ("Module 1,exit!/n"); Export_symbol (FUNC1); Module_init (Hello_init); Module_exit (Hello_exit);
Mod2.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
Module_license ("DUAL BSD/GPL");
extern int func1 (void);
Static int func2 (void)
{
func1 ();
PRINTK ("in Func:%s.../n", __func__);
return 0;
}
Static int __init hello_init (void)
{
PRINTK ("Module 2,init!/n");
FUNC2 ();
return 0;
}
static void __exit hello_exit (void)
{
PRINTK ("Module 2,exit!/n");
}
Module_init (hello_init);
Module_exit (Hello_exit);
//makefile
Ifneq ($ (kernelrelease),) obj-m : = Xxx.oelsekdir : =/lib/modules/$ (Shell uname-r)/buildpwd : = $ (Shell pwd ) default:$ (make)-C $ (Kdir) subdirs=$ (PWD) modulesclean:rm-rf module.symvers *.ko *.o *.mod.c. *.cmd. tmp_versions *~ * * ~endif
2. Operation
There are two modules, mod1 and MOD2.
The func () 1 function is defined in MOD1 and is exported by Export_symbol ().
In Mod2, extern func () 1, called Func () 1.
①insmod Mod1.ko
② Insmod Mod2.ko
Compile module MOD2, success.
When loading mod2, output:
Insmod:error inserting ' Mod2.ko ':-1 Invalid parameters
DMESG View:
Mod2:no symbol version for Func
Mod2:unknown symbol func (err-22)
③cat /proc/kallsyms |grep func1
After knowing what the kernel symbol table is, we go back to the previous question.
We look at/proc/kallsyms and find that the mod1 func function has a flag of T, and this flag indicates that the function is local.
This issue is a bug that follows kernel 2.6.26 and will not be repaired
3. Solutions
(1) Put mod1 module.symvers in mod2 so that the symbolic information will be automatically linked when compiling the MOD2.
(2) Adding symbolic information to the makefile of MOD2
Echo ' 0x01873e3f func mod1 export_symbol_gpl ' > Module.symvers
This way MOD2 knows the address of the Func symbol in MOD1 at compile time.
Q: What is the cause of this problem?
A: When generating mod2, do not know the mod1 in the Func checksum code, MOD2 load when checking the checksum error.
In the kernel mainline code tree A commit modifies the kernel Mount module when the function version check mechanism, so that in the Mount module when the compilation
When an individual function is not determined, the CRC checksum cannot be checked by the Check_version function.
This is the module mount of the kernel intended to prohibit the existence of individual versions of a function without version checksum information.
Linux driver Export_symbol function and 2.6 kernel Unknown SYMBOL bug Resolution