Kernel Module Headers
In recent projects, we need to hack on Linux Kernel with various customization on multiple architectures. However, common distros like Fedora/Debian/Centos will not provide compatible kernel development headers (staffs under /lib/modules/$version) required by building kernel modules.
For example, if we compile a kernel module without a compatible kernel development header, it complains:
make -C /lib/modules/6.1.11/build M=... modules
make[1]: *** /lib/modules/6.1.11/build: No such file or directory.  Stop.
make: *** [Makefile:6: all] Error 2
To fix this issue, we have to build ourselves a kernel development header from the source. It took some time to find a solution.
Build Kernel Module Preparation
First, we should get the exact version of the source code and the same configuration (.config) with your customized kernel. Then, run modules_prepare target.
Note that modules_prepare target will not generate Module.symvers, which contains a list of exported symbols from a kernel build. Module.symvers is crucial for module versioning but is not necessary for an experimental kernel module. Run a full kernel build if we need Module.symvers.
Copy this kernel directory to /usr/src and rename.
Link it to /lib/modules/6.1.11/build.
Done!
Test with a Kernel Module
We test the self-built kernel development header with an example kernel module (hello.c) from The Linux Kernel Module Programming Guide
Source code:
/* 
 * hello.c - The simplest kernel module. 
 */ 
#include <linux/kernel.h> /* Needed for pr_info() */ 
#include <linux/module.h> /* Needed by all modules */ 
int init_module(void) 
{ 
    pr_info("Hello world.\n"); 
    /* A non 0 return means init_module failed; module can't be loaded. */ 
    return 0; 
} 
void cleanup_module(void) 
{ 
    pr_info("Goodbye world.\n"); 
} 
MODULE_LICENSE("GPL");
Building script:
obj-m += hello.o
PWD := $(CURDIR) 
all: 
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 
clean: 
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Build and test:
$ make
$ (sudo) insmod hello.ko
[15394.319943] hello: loading out-of-tree module taints kernel.
[15394.371244] Hello world.
$ (sudo) rmmod hello
[15436.280762] Goodbye world.
Cheers!