无法让多文件内核模块工作

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