Build Kernel Modules During Kernel Compilation: Complete Guide with Steps

In most cases, Linux kernel modules are built out-of-tree, meaning separately from the kernel source tree. However, when your module is critical or tightly coupled with kernel internals, it’s beneficial to build it in-tree—as part of the actual kernel compilation process.

This approach ensures:

  • Compatibility with kernel headers and configs
  • Automatic compilation during make
  • Ease of deployment for embedded or custom distributions

In this post, you’ll learn:

  • Folder placement of kernel modules
  • Updating Makefile and Kconfig
  • How to test the compiled module
  • How to enable/disable it from kernel menuconfig

📦 Kernel Version Used in Example

We assume a Linux kernel source tree is already downloaded (e.g., linux-5.10/), and you’re running these commands from the base directory.


✅ Step 1: Create Your Kernel Module Source

Create a directory inside the kernel source tree, for example under drivers/hello_world/.

cd linux-5.10
mkdir -p drivers/hello_world

Now create a simple kernel module file:

hello.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple kernel module built in-tree");

static int __init hello_init(void) {
    printk(KERN_INFO "Hello Kernel!\n");
    return 0;
}

static void __exit hello_exit(void) {
    printk(KERN_INFO "Goodbye Kernel!\n");
}

module_init(hello_init);
module_exit(hello_exit);

Explanation:
This code defines a basic loadable module with init and exit functions. printk() is used to log kernel messages. This will be compiled along with the kernel tree.


📘 Step 2: Create a Module Makefile

Inside drivers/hello_world/, create a Makefile:

Makefile

obj-$(CONFIG_HELLO_MODULE) += hello.o

Explanation:
This instructs the kernel build system to include hello.o in compilation if the CONFIG_HELLO_MODULE flag is set to y or m (module).


✏️ Step 3: Register the Module in Main Kernel Makefiles

Edit drivers/Makefile and add the following line at the end:

obj-$(CONFIG_HELLO_MODULE) += hello_world/

Then edit drivers/Kconfig to add:

menu "Hello World Module"

config HELLO_MODULE
    tristate "Build Hello Kernel Module"
    default m
    help
      This is a simple example kernel module compiled with the kernel.

endmenu

Explanation:
This makes your module configurable via make menuconfig or make nconfig. You can choose to build it as a module (m), built-in (y), or exclude it (n).


🔄 Step 4: Enable Module in Kernel Config

Run:

make menuconfig

Then go to Device Drivers → Hello World Module → Build Hello Kernel Module
Select M for module (recommended for testing).

Save and exit.


🛠 Step 5: Compile the Kernel with Your Module

Now build your kernel:

make -j$(nproc)

Or for just modules:

make modules -j$(nproc)

Explanation:
This will also compile your module as hello.ko inside drivers/hello_world/ if CONFIG_HELLO_MODULE=m.


🧪 Step 6: Load and Test the Module

Install the compiled modules:

sudo make modules_install

Then insert the module:

sudo modprobe hello

Or manually:

sudo insmod drivers/hello_world/hello.ko

Check dmesg:

dmesg | tail

You should see:

[ 1234.567 ] Hello Kernel!

To remove the module:

sudo rmmod hello

⚠️ Common Mistakes to Avoid

MistakeWhy It’s a Problem
Missing Makefile or obj lineThe kernel won’t see your module
Skipping Kconfig registrationModule won’t be selectable via menuconfig
Wrong file permissions in .c or MakefileCompiler may skip or error during build
Using printk incorrectlyMay cause kernel panic or missed debug logs

🧠 Best Practices for In-Tree Kernel Modules

  • Keep modules in a separate subfolder (like drivers/my_module/)
  • Use CONFIG_ flags to control inclusion via Kconfig
  • Always test with modprobe, insmod, and rmmod
  • Follow kernel coding style: use checkpatch.pl before commit
  • Version control only your module, not the whole kernel tree

🧪 Use Case: Add In-Tree Module for Embedded Linux Device

For embedded products (like routers, IoT devices, or custom SBCs), you often compile your own kernel. Embedding your module ensures:

  • Portability across devices
  • Simplified deployment
  • No need for DKMS or separate builds

💡 Final Thoughts

Building a kernel module as part of the Linux kernel compilation is a powerful technique when working with custom, embedded, or secure environments. It ensures your code is always compiled with matching headers and eliminates post-build incompatibility.

Whether you’re building drivers or adding extensions to the kernel, in-tree module integration offers stability, control, and automation.

Have you added a custom module to your kernel tree? Share your repo or command-line approach below—let’s learn together!

Leave a Comment