无法让多文件内核模块工作
Can't get multi files kernel module to work
我正在尝试使用多个源文件构建可加载内核模块。根据 https://www.kernel.org/doc/Documentation/kbuild/makefiles.txt 的第 3.3 节,我必须将 obj-m 用于主目标文件,将 modulename-y 用于其余部分。
这是我的 mwe:
helpers.h
#ifndef __HELPERS_H__
#define __HELPERS_H__
void helper_print_init(void);
void helper_print_exit(void);
#endif // __HELPERS_H__
helpers.c
#include "helpers.h"
#include <linux/kernel.h>
void helper_print_init(void) {
printk("multi_file_ko_init_helper\n");
}
void helper_print_exit(void) {
printk("multi_file_ko_exit_helper\n");
}
multiFileKo.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
//#include "helpers.h"
static int __init multi_file_ko_init(void) {
printk("multi_file_ko_init\n");
// helper_print_init();
return 0;
}
static void __exit multi_file_ko_exit(void) {
printk("multi_file_ko_exit\n");
// helper_print_exit();
}
module_init(multi_file_ko_init);
module_exit(multi_file_ko_exit);
MODULE_LICENSE("MIT");
MODULE_AUTHOR("AUTHOR");
MODULE_DESCRIPTION("gpio");
MODULE_VERSION("0.0");
请注意 multiFileKo.c 目前甚至没有实际使用助手。我试图实际调用这些函数,但为了简单起见,我只是从 mwe 中注释掉了一些东西。
现在,如果我像下面这样用 kbuild 编译它,只使用主文件,我会得到预期的 dmesg 输出:
obj-m := multiFileKo.o
但是当我尝试编译它与助手链接时,即使没有像下面这样实际使用它们,dmesg 仍然保持沉默,即使 insmod/rmmod 似乎在工作:
obj-m := multiFileKo.o
multiFileKo-y := helpers.o
显然,如果我取消注释 multiFileKo.c 中的所有内容,它也不起作用。因此,无论附加目标文件做什么,链接附加目标文件的事实似乎都会破坏我的模块。
multiFileKo-objs 的方法对我也不起作用。我之前看到过这个,但确定这是它的起源,因为 makefile 手册仅在主机程序的上下文中使用它。
导致解决方案的信息由@Tsyvarev 提供。原始信息可以在第一个 post.
的评论中找到
obj-m := multiFileKo.o
定义模块名称。它还默认使用 multiFileKo.c 作为源文件。但是这个原则只适用于单源文件模块。
如果使用多个源文件创建一个模块,obj-m := multiFileKo.o
应定义模块名称,而不是源文件。 ALL 目标文件(引用实际来源)然后应列在 multiFileKo-objs :=
列表中。源文件不允许与模块同名。
根据我的实验和制作实用程序手册,我还可以说在 multiFileKo-y :=
中列出源似乎也有效。由于兼容性,可能 -obj
仍在工作,因为 make 文档现在建议使用 -y
列表。
总而言之,正确的做法是:
obj-m := multiFileKo.o
multiFileKo-y := multiFileKo_main.o helpers.o
源文件:
multiFileKo_main.c // contains init and exit functions
helpers.c
输出将存储在 multiFileKo.ko
我正在尝试使用多个源文件构建可加载内核模块。根据 https://www.kernel.org/doc/Documentation/kbuild/makefiles.txt 的第 3.3 节,我必须将 obj-m 用于主目标文件,将 modulename-y 用于其余部分。 这是我的 mwe:
helpers.h
#ifndef __HELPERS_H__
#define __HELPERS_H__
void helper_print_init(void);
void helper_print_exit(void);
#endif // __HELPERS_H__
helpers.c
#include "helpers.h"
#include <linux/kernel.h>
void helper_print_init(void) {
printk("multi_file_ko_init_helper\n");
}
void helper_print_exit(void) {
printk("multi_file_ko_exit_helper\n");
}
multiFileKo.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
//#include "helpers.h"
static int __init multi_file_ko_init(void) {
printk("multi_file_ko_init\n");
// helper_print_init();
return 0;
}
static void __exit multi_file_ko_exit(void) {
printk("multi_file_ko_exit\n");
// helper_print_exit();
}
module_init(multi_file_ko_init);
module_exit(multi_file_ko_exit);
MODULE_LICENSE("MIT");
MODULE_AUTHOR("AUTHOR");
MODULE_DESCRIPTION("gpio");
MODULE_VERSION("0.0");
请注意 multiFileKo.c 目前甚至没有实际使用助手。我试图实际调用这些函数,但为了简单起见,我只是从 mwe 中注释掉了一些东西。
现在,如果我像下面这样用 kbuild 编译它,只使用主文件,我会得到预期的 dmesg 输出:
obj-m := multiFileKo.o
但是当我尝试编译它与助手链接时,即使没有像下面这样实际使用它们,dmesg 仍然保持沉默,即使 insmod/rmmod 似乎在工作:
obj-m := multiFileKo.o
multiFileKo-y := helpers.o
显然,如果我取消注释 multiFileKo.c 中的所有内容,它也不起作用。因此,无论附加目标文件做什么,链接附加目标文件的事实似乎都会破坏我的模块。
multiFileKo-objs 的方法对我也不起作用。我之前看到过这个,但确定这是它的起源,因为 makefile 手册仅在主机程序的上下文中使用它。
导致解决方案的信息由@Tsyvarev 提供。原始信息可以在第一个 post.
的评论中找到obj-m := multiFileKo.o
定义模块名称。它还默认使用 multiFileKo.c 作为源文件。但是这个原则只适用于单源文件模块。
如果使用多个源文件创建一个模块,obj-m := multiFileKo.o
应定义模块名称,而不是源文件。 ALL 目标文件(引用实际来源)然后应列在 multiFileKo-objs :=
列表中。源文件不允许与模块同名。
根据我的实验和制作实用程序手册,我还可以说在 multiFileKo-y :=
中列出源似乎也有效。由于兼容性,可能 -obj
仍在工作,因为 make 文档现在建议使用 -y
列表。
总而言之,正确的做法是:
obj-m := multiFileKo.o
multiFileKo-y := multiFileKo_main.o helpers.o
源文件:
multiFileKo_main.c // contains init and exit functions
helpers.c
输出将存储在 multiFileKo.ko