Я работаю в Ubuntu. Я пытаюсь сделать два модуля ядра, которые используют друг друга. Моя проблема в том, что я правильно модулировал модули, но символ не разрешен для одного из них.
Чтобы сделать все просто, позвоните этим модулям как m1
и m2
.
m2 экспортирует функцию void func_m2(void)
. m1
вызывает эту функцию. Оба модуля правильно компилируются.
После того как все компилируется, мне нужно сначала загрузить модуль m2
(потому что он экспортировал функцию func_m2
), а затем m1
. Итак, позвольте сделать это:
[email protected]:~/development/kmodules/m2$ sudo insmod ./m2.ko
Теперь загрузите модуль m1
, который пытается использовать func_m2
:
[email protected]:~/development/kmodules/m1$ sudo insmod ./m1.ko
insmod: error inserting './m1.ko': -1 Unknown symbol in module
Ниже приводится то, что я вижу в журналах:
[email protected]:~/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
не разрешены. Интересно. Проверьте, присутствует ли в таблице символов:
[email protected]:~/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, который я использовал для этого теста, для модулей 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");
Makefile:
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);
Makefile:
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
?
Было бы полезно, если бы кто-то мог ответить.