- Why Compile Your Own Kernel?
- Compiling the Linux Kernel
- Kernel Configuration
- Writing a Kernel Module
- DKMS β Dynamic Kernel Module Support
- Practice Exercises
| Reason | Example |
|---|---|
| Enable specific features | Real-time patches, new filesystems |
| Remove bloat | Smaller kernel for embedded/VMs |
| Hardware support | Custom drivers not in mainline |
| Security | Remove unused features = smaller attack surface |
| Learning | Understand Linux internals deeply |
# Install dependencies
sudo apt install build-essential libncurses-dev bison flex libssl-dev \
libelf-dev dwarves bc rsync
# Download kernel source
cd /usr/src
sudo wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.8.tar.xz
sudo tar -xJf linux-6.8.tar.xz
cd linux-6.8# Start from current config
cp /boot/config-$(uname -r) .config
make olddefconfig # Accept defaults for new options
# Or interactive configuration
make menuconfig # TUI (recommended)
make xconfig # Qt GUI
make nconfig # Newer TUI# Compile (use all CPU cores)
make -j$(nproc)
# Compile modules
make modules -j$(nproc)
# Install modules
sudo make modules_install
# Install kernel
sudo make install
# Update bootloader
sudo update-grub # Debian/Ubuntu
sudo grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL/Fedora
# Reboot to new kernel
sudo reboot
uname -r # VerifyGeneral setup β
Local version: -custom # Append to kernel version
Default hostname: myhost
Processor type and features β
Processor family: (select yours)
Preemption Model: (desktop vs server)
Enable block layer β
IO Schedulers: (select needed ones)
File systems β
Btrfs, XFS, ext4, etc.
Networking support β
Networking options β
TCP/IP networking
Network packet filtering (Netfilter)
Device Drivers β
(Enable/disable hardware support)
Security options β
SELinux, AppArmor, etc.
# Enable only modules currently in use
make localmodconfig # Uses lsmod to determine needed modules
# Minimal config
make tinyconfig # Absolute minimal kernel
# Compare configs
scripts/diffconfig .config.old .config// hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sovon");
MODULE_DESCRIPTION("Hello World Kernel Module");
MODULE_VERSION("1.0");
static int __init hello_init(void) {
printk(KERN_INFO "Hello from kernel module!\n");
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "Goodbye from kernel module!\n");
}
module_init(hello_init);
module_exit(hello_exit);obj-m += hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) cleanmake # Compile
sudo insmod hello.ko # Load module
dmesg | tail -1 # "Hello from kernel module!"
lsmod | grep hello # Verify loaded
sudo rmmod hello # Unload
dmesg | tail -1 # "Goodbye from kernel module!"#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
static int count = 1;
static char *name = "world";
module_param(count, int, 0644);
MODULE_PARM_DESC(count, "Number of greetings");
module_param(name, charp, 0644);
MODULE_PARM_DESC(name, "Name to greet");
static int __init hello_init(void) {
int i;
for (i = 0; i < count; i++)
printk(KERN_INFO "Hello, %s!\n", name);
return 0;
}
// ... exit function and module macrossudo insmod hello.ko count=3 name="Linux"DKMS automatically rebuilds modules when the kernel is upgraded.
sudo apt install dkms
# Create DKMS structure
sudo mkdir /usr/src/hello-1.0/
sudo cp hello.c Makefile /usr/src/hello-1.0/
# Create dkms.conf
sudo tee /usr/src/hello-1.0/dkms.conf << 'EOF'
PACKAGE_NAME="hello"
PACKAGE_VERSION="1.0"
BUILT_MODULE_NAME[0]="hello"
DEST_MODULE_LOCATION[0]="/updates/dkms"
AUTOINSTALL="yes"
MAKE[0]="make -C /lib/modules/${kernelver}/build M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
CLEAN="make -C /lib/modules/${kernelver}/build M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build clean"
EOF
# Register and build
sudo dkms add -m hello -v 1.0
sudo dkms build -m hello -v 1.0
sudo dkms install -m hello -v 1.0
# Status
dkms status- Config: Copy your current kernel config and explore
make menuconfig - (VM) Compile a custom kernel with a different
LOCALVERSIONstring - Module: Build and load the hello world kernel module
- Params: Modify the module to accept parameters
- dmesg: Watch kernel messages while loading/unloading modules
- DKMS: Package your module with DKMS
β Previous: LVM & RAID Β· π Home Β· Next: Docker & Containers β