你好世界 C++ 内核模块中的未定义符号
Undefined symbols in hello world C++ kernel module
我已将 C++ 支持添加到 Linux 内核版本 4.14.41,编译它并使用内核成功启动。我可以通过插入 LKM
来检查 C++ 模块的正确性。这是我要加载的模块:
#include<c++/begin_include.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include<c++/end_include.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LKM in c++");
MODULE_AUTHOR("MOOL");
class hello
{
public:
hello();
void hi();
};
void hello::hi()
{
printk("Hello world!! \n");
}
hello::hello()
{
printk("Constructor is being called \n");
}
extern "C"
{
static int __init test_classes_init()
{
class hello obj;
obj.hi();
printk("Module inserted:\n");
return 0;
}
static void __exit test_classes_fini()
{
printk("Module removed:\n");
}
module_init(test_classes_init);
module_exit(test_classes_fini);
}
生成文件:
obj-m = helloworld.o
KVERSION=$(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
当我输入 make 命令时,生成了 helloworld.ko
和警告
WARNING: "begin_fini" [/home/jai/Downloads/helloworld/helloworld.ko] undefined !
WARNING: "end_init" [/home/jai/Downloads/helloworld/helloworld.ko] undefined !
WARNING: "begin_init" [/home/jai/Downloads/helloworld/helloworld.ko] undefined !
但是当我尝试使用 insmod helloworld.ko
插入它时,出现 undefined symbol
错误。
dmesg:
loading out-of-tree module taints kernel
Unknown symbol begin_init (err 0)
Unknown symbol end_init (err 0)
Unknown symbol begin_fini (err 0)
这些begin_init
、end_init
和begin_fini
定义在lib/gcc/crtstuff.c
中(已移植到内核中)。这些函数在 crtstuff.c
和 linux/module.h
中都声明为 extern
。这个 module.h
被包含在上面的 helloworld
模块中,但这些符号仍然未定义。那么,如何定义这些函数?
您的内核 C++ 实现不完整。您将必须实现全局构造函数和析构函数支持(正确处理 .init_array
和 .fini_array
部分),或者停止在源代码中使用这些 C++ 功能。这需要内核模块加载器的配合。对启动代码的更改将不起作用,因为启动代码未链接到内核模块。
我已将 C++ 支持添加到 Linux 内核版本 4.14.41,编译它并使用内核成功启动。我可以通过插入 LKM
来检查 C++ 模块的正确性。这是我要加载的模块:
#include<c++/begin_include.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include<c++/end_include.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LKM in c++");
MODULE_AUTHOR("MOOL");
class hello
{
public:
hello();
void hi();
};
void hello::hi()
{
printk("Hello world!! \n");
}
hello::hello()
{
printk("Constructor is being called \n");
}
extern "C"
{
static int __init test_classes_init()
{
class hello obj;
obj.hi();
printk("Module inserted:\n");
return 0;
}
static void __exit test_classes_fini()
{
printk("Module removed:\n");
}
module_init(test_classes_init);
module_exit(test_classes_fini);
}
生成文件:
obj-m = helloworld.o
KVERSION=$(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
当我输入 make 命令时,生成了 helloworld.ko
和警告
WARNING: "begin_fini" [/home/jai/Downloads/helloworld/helloworld.ko] undefined !
WARNING: "end_init" [/home/jai/Downloads/helloworld/helloworld.ko] undefined !
WARNING: "begin_init" [/home/jai/Downloads/helloworld/helloworld.ko] undefined !
但是当我尝试使用 insmod helloworld.ko
插入它时,出现 undefined symbol
错误。
dmesg:
loading out-of-tree module taints kernel
Unknown symbol begin_init (err 0)
Unknown symbol end_init (err 0)
Unknown symbol begin_fini (err 0)
这些begin_init
、end_init
和begin_fini
定义在lib/gcc/crtstuff.c
中(已移植到内核中)。这些函数在 crtstuff.c
和 linux/module.h
中都声明为 extern
。这个 module.h
被包含在上面的 helloworld
模块中,但这些符号仍然未定义。那么,如何定义这些函数?
您的内核 C++ 实现不完整。您将必须实现全局构造函数和析构函数支持(正确处理 .init_array
和 .fini_array
部分),或者停止在源代码中使用这些 C++ 功能。这需要内核模块加载器的配合。对启动代码的更改将不起作用,因为启动代码未链接到内核模块。