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

Posted

技术标签:

【中文标题】无法让多文件内核模块工作【英文标题】:Can't get multi files kernel module to work 【发布时间】:2021-12-31 16:18:57 【问题描述】:

我正在尝试使用多个源文件构建可加载的内核模块。根据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 的方法对我也不起作用。我之前看到过这个,但可以确定它的来源,因为 makefiles 手册仅在主机程序的上下文中使用它。

【问题讨论】:

显示您的整个Makefile 这能回答你的问题吗? Building a kernel module from several source files which one of them has the same name as the module 您的问题的核心是您的内核模块由多个源文件组成,并且该源文件之一的名称 - multiFileKo.c - 与模块本身的名称 (multiFileKo) 一致。 @MarcoBonelli 这是整个生成文件 "为什么当它是单源文件模块时它可以工作,如果它是多源文件则不行?" - 您的 Makefile 没有正确指定多个源文件。在当前形式中,multiFileKo-y := helpers.o 行是无用。被重写为multiFileKo-objs := helpers.o 的行将从单个源文件 - helpers.c 构建模块。因为这个文件不包含“init”和“exit”函数,所以加载和卸载你的模块什么都不做。 【参考方案1】:

导致解决方案的信息由@Tsyvarev 提供。原始信息可以在 cmets 中找到第一次发布。

obj-m := multiFileKo.o 定义模块的名称。它还默认使用 multiFileKo.c 作为源文件。但是这个原则只适用于单源文件模块。

如果使用多个源文件来创建一个模块,obj-m := multiFileKo.o 应定义模块名称,但不定义源。 ALL 目标文件(参考实际来源)应列在multiFileKo-objs := 列表中。源文件不允许与模块同名。

从我的实验和制作实用手册中,我也可以说在multiFileKo-y := 中列出来源似乎也有效。也许-obj 由于兼容性而仍在工作,因为现在制作文档建议使用-y 列表。

总而言之,正确的做法是:

obj-m := multiFileKo.o
multiFileKo-y := multiFileKo_main.o helpers.o

源文件:

multiFileKo_main.c // contains init and exit functions
helpers.c

输出将存储在multiFileKo.ko

【讨论】:

以上是关于无法让多文件内核模块工作的主要内容,如果未能解决你的问题,请参考以下文章

无法在内核模块 makefile 中使用通配符

内核模块

无法加载内核模块“nvidia.ko”

《linux内核设计与分析》内核模块编程

linux 模块编译无法生成.ko文件,显示如下信息,请问是啥原因啊?

如何使用预构建的内核输出目录构建Linux内核模块?