我在 Ubuntu 工作。我正在尝试制作两个使用彼此功能的内核模块。我的问题是我得到了正确编译的模块,但是其中一个没有解析符号。
为简单起见,我们将这些模块称为m1
和m2
。
m2 是导出功能void func_m2(void)
。m1
正在调用此函数。两个模块都能正确编译。
全部编译完成后,我需要先加载m2
模块(因为它具有导出func_m2
功能),然后再加载m1
模块。所以,让我们实现它:
volodymyr@sv1:~/development/kmodules/m2$ sudo insmod ./m2.ko
现在,让我们加载m1
正在尝试使用的模块func_m2
:
volodymyr@sv1:~/development/kmodules/m1$ sudo insmod ./m1.ko
insmod: error inserting './m1.ko': -1 Unknown symbol in module
以下是我在日志中看到的内容:
volodymyr@sv1:~/development/kmodules/m1$ dmesg | tail
[ 3938.166616] Loading m2 module ...
[ 3963.078055] m1: no symbol version for func_m2
[ 3963.078059] m1: Unknown symbol func_m2
因此,似乎对符号的引用func_m2
没有解决。有趣的。让我们检查它是否存在于符号表中:
volodymyr@sv1:~/development/kmodules$ cat /proc/kallsyms | grep 'func_m2'
ffffffffa00530d0 r __ksymtab_func_m2 [m2]
ffffffffa00530e8 r __kstrtab_func_m2 [m2]
ffffffffa00530e0 r __kcrctab_func_m2 [m2]
ffffffffa0053000 T func_m2 [m2]
000000004edd543f a __crc_func_m2 [m2]
如您所见,func_m2
实际上存在于符号表中。那么为什么m1
加载不出来呢?
我已经为我的内核和 Linux 源正确安装了 Linux 头文件。我没有对内核进行任何修改,它没有被修改,它的版本是:2.6.31-16-generic(我运行 x64)
现在,为了向您展示全貌,我将源代码和 Makefile 我用于此测试的源代码和 Makefile 放在m1
这里m2
。
m1
模块:
m1.c:
#include <linux/module.h>
#include <linux/kernel.h>
extern void func_m2(void);
int hello_start(void)
{
printk(KERN_INFO "Loading m1 module ...\n");
func_m2();
return 0;
}
void hello_end(void)
{
printk(KERN_INFO "Unloading m1 ...\n");
}
module_init(hello_start);
module_exit(hello_end);
MODULE_LICENSE("GPL");
生成文件:
obj-m := m1.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
m2
模块:
m2.c:
#include <linux/module.h>
#include <linux/kernel.h>
int hello_start(void)
{
printk(KERN_INFO "Loading m2 module ...\n");
return 0;
}
void hello_end(void)
{
printk(KERN_INFO "Unloading m2 ...\n");
}
void func_m2(void)
{
printk(KERN_INFO "This a function in m2\n");
}
module_init(hello_start);
module_exit(hello_end);
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(func_m2);
生成文件:
obj-m := m2.o
export-objs := m2.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
基本上我的问题是:为什么不能m1
加载?
如果有人能回答会很有帮助。