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
andKconfig
- 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
Mistake | Why It’s a Problem |
---|---|
Missing Makefile or obj line | The kernel won’t see your module |
Skipping Kconfig registration | Module won’t be selectable via menuconfig |
Wrong file permissions in .c or Makefile | Compiler may skip or error during build |
Using printk incorrectly | May 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
, andrmmod
- 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!