0

I'm trying to build a loadable kernel module using multiple source files. According to section 3.3 of https://www.kernel.org/doc/Documentation/kbuild/makefiles.txt I've got to use obj-m for main object file and modulename-y for the rest of it. Here's my 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");

NOTE THAT multiFileKo.c does not even actually uses helpers for now. I tried to actually call those functions but for simplicity just commented things out from mwe.

Now if I compile it with kbuild like follows, using only main file, I get dmesg output as expected:

obj-m := multiFileKo.o

But when I try to compile it linked with helpers, even without actually using them as follows, dmesg remains silent even though insmod/rmmod seem to be working:

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

Obviously if I uncomment everything in multiFileKo.c it does not work either. So the fact of linking additional object file seems to be breaking my module regardless of what that additional object file does.

Approach with multiFileKo-objs does not work for me either. I saw this earlier, but sure where this takes it's origin, since makefiles manual uses it only in context of host programs.

Roman
  • 1,396
  • 4
  • 15
  • 39
  • Show your entire `Makefile` – Marco Bonelli Nov 22 '21 at 00:46
  • 2
    Does this answer your question? [Building a kernel module from several source files which one of them has the same name as the module](https://stackoverflow.com/questions/13606075/building-a-kernel-module-from-several-source-files-which-one-of-them-has-the-sam) – Tsyvarev Nov 22 '21 at 07:19
  • 1
    The core of your problem is that your kernel module consists from several source files and name of one of this source file - `multiFileKo.c` - coincides with the name of the module itself (`multiFileKo`). – Tsyvarev Nov 22 '21 at 07:20
  • @MarcoBonelli this is the entire makefile – Roman Nov 22 '21 at 10:29
  • @Tsyvarev I'll test it this night. My understanding was that it HAS TO be like that. That source contains init and exit functions, so I thought it's kind of convention. Suppose it solves the issue, why does it work when it's single-source-file module, doesn't if it's multiple-source-files? – Roman Nov 22 '21 at 10:33
  • 1
    "why does it work when it's single-source-file module, doesn't if it's multiple-source-files?" - Your Makefile doesn't specify multiple source files correctly. In current form, the line `multiFileKo-y := helpers.o` is **useless**. Being rewritten as `multiFileKo-objs := helpers.o` the line would build the module from the **single source file** - `helpers.c`. Because this file doesn't contain "init" and "exit" functions, loading and unloading of your module does nothing. – Tsyvarev Nov 22 '21 at 10:44
  • @Tsyvarev So obj-m := multiFileKo.o does actually result in multiFileKo.c build only when we're compiling single-file kernel object, and when we have more then one source file obj-m effectively just defines kernel module name and all actual object files which are compiled from sources have to be listed in targetName-objs list? – Roman Nov 22 '21 at 12:10
  • Line `obj-m := multiFileKo.o` tells to build module `multiFileKo`. **By default**, the module will be compiled from the single source file with the same name - `multiFileKo.c`. Assigning to the variable `multiFileKo-objs` specifies **complete** source list for the module. This source list replaces the default one. – Tsyvarev Nov 22 '21 at 12:31
  • In other words, your last comment is correct. – Tsyvarev Nov 22 '21 at 12:37
  • And `multiFileKo-objs` cannot contain `multiFileKo.o`, so you cannot have `multiFileKo.c`. – Ian Abbott Nov 22 '21 at 14:07
  • @Tsyvarev Thanks a lot! The main issue was wrong understanding of how obj-m works for single- and multiple- file modules. I've also tried to compile things with targetName-y instead of targetName-objs and it works. As I've mentioned earlier this is how makefile docs command to do this. A bit of clarification would be nice here. Could you also please create an answer to the question so I could accept it? – Roman Nov 22 '21 at 18:41

1 Answers1

1

Info which lead to solution was provided by @Tsyvarev. Original info may be found in comments to first post.

obj-m := multiFileKo.o defines the name of module. It also uses multiFileKo.c as a source file by default. But this principle works for single-source-file modules only.

In case multiple source files are used to create a module, obj-m := multiFileKo.o shall define module name, but not the sources. ALL object files (referencing actual sources) then shall be listed in multiFileKo-objs := list. Source files are not allowed to have the same name which module have.

From my experiments and make utility manual I can also say that it seems that listing sources in multiFileKo-y := also works. Maybe -obj is still working due to compatibility, since make documents now advise to use -y list.

To sum up, correct approach would be:

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

Source files:

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

Output would be stored in multiFileKo.ko

Roman
  • 1,396
  • 4
  • 15
  • 39