Hellin
Hellin

Reputation: 23

Kernel Makefile does not create any .ko file for my module

I want to make very simple module. So, I just made a hello_module.c file and a Makefile.

Makefile:

obj-m := hello_module.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
    $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules

clean:
    $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) clean

hello_module.c:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kthread.h> // for thread
#include <linux/slab.h> // for kmalloc
#include <linux/delay.h>

int test_thread(void * _arg) {
        int * arg = (int * ) _arg;
        printk("argument : %d\n", * arg);
        kfree(arg);
        return 0;
}

void thread_create(void) {
        int i;
        /* thread create */
        for (i = 0; i < 10; i++) {
                int * arg = (int * ) kmalloc(sizeof(int), GFP_KERNEL);
                * arg = i;
                kthread_run( & test_thread, (void * ) arg, "test_thread");
        }
}

int __init hello_module_init(void) {
        thread_create();
        printk(KERN_EMERG "Hello Module\n");
        return 0;
}

But, It didn't make any .ko file. Also, There is no error.

The result is as follows:

rashta@rashta-VirtualBox:~/Desktop/ehh$ sudo make
[sudo] password for rashta:
make -C /lib/modules/5.4.71yujin/build SUBDIRS=/home/rashta/Desktop/ehh modules
make[1]: Entering directory '/usr/src/linux-5.4.71'
CALL    scripts/checksyscalls.sh
CALL    scripts/atomic/check-atomics.sh
DESCEND  objtool
CHK     kernel/kheaders_data.tar.xz
Building modules, stage 2.
MODPOST 5483 modules
make[1]: Leaving directory '/usr/src/linux-5.4.71'

What am I doing wrong?

Upvotes: 1

Views: 4130

Answers (2)

Tsyvarev
Tsyvarev

Reputation: 65996

For a long time kbuild treated SUBDIRS= parameter in the same way as M=. It is no longer true after Linux kernel 5.3: support for SUBDIRS= has been dropped.

So, instead of SUBDIRS=$(PWD) one should use M=$(PWD).

One could find following warning in the Makefile for 5.3 version (but not after!):

ifdef SUBDIRS
  $(warning ================= WARNING ================)
  $(warning 'SUBDIRS' will be removed after Linux 5.3)
  $(warning )
  $(warning If you are building an individual subdirectory)
  $(warning in the kernel tree, you can do like this:)
  $(warning $$ make path/to/dir/you/want/to/build/)
  $(warning (Do not forget the trailing slash))
  $(warning )
  $(warning If you are building an external module,)
  $(warning Please use 'M=' or 'KBUILD_EXTMOD' instead)
  $(warning ==========================================)
  KBUILD_EXTMOD ?= $(SUBDIRS)
endif

Upvotes: 1

Marco Bonelli
Marco Bonelli

Reputation: 69357

Your Makefile is wrong. In order to build a kernel module, you need to pass M=, not SUBDIRS=. This should work:

obj-m      := hello_module.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD        := $(shell pwd)

default:
    $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean

Also, your module is missing some parts to successfully compile, namely the module_init() macro defining which function to use. Add the following to your code:

void __exit hello_module_exit(void) {
    // Not required, but needed to be able to unload the module.
    return;
}

module_init(hello_module_init);
module_exit(hello_module_exit);
MODULE_VERSION("0.1");
MODULE_DESCRIPTION("Test module");
MODULE_AUTHOR("You");
MODULE_LICENSE("GPL");

Upvotes: 1

Related Questions