| name | kbuild |
| description | Guide for the Linux Kernel Build System (Kbuild). Use when building kernel modules out-of-tree, creating module Makefiles, or integrating with the kernel build infrastructure. Essential for proper kernel module compilation. |
Kbuild - Linux Kernel Build System
Out-of-Tree Module Makefile
Standard Makefile for external kernel modules:
# If KERNELRELEASE is defined, we've been invoked from the kernel build system
ifneq ($(KERNELRELEASE),)
obj-m := mymodule.o
# Otherwise we were called directly from the command line
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
endif
Kbuild Variables
obj-m and obj-y
# Build as module (.ko)
obj-m := mymodule.o
# Build into kernel (in-tree only)
obj-y := mymodule.o
# Conditional based on config
obj-$(CONFIG_MY_DRIVER) := mydriver.o
Multi-file Modules
# Module from multiple source files
obj-m := mymodule.o
mymodule-objs := main.o utils.o hardware.o
# Alternative syntax
mymodule-y := main.o utils.o hardware.o
Multiple Modules
obj-m := module1.o module2.o
module1-objs := mod1_main.o mod1_util.o
module2-objs := mod2_main.o
Compiler Flags
# Extra flags for all files in this directory
ccflags-y := -DDEBUG -I$(src)/include
# Flags for specific file
CFLAGS_main.o := -DSPECIAL_FLAG
# Linker flags
ldflags-y := -T$(src)/module.lds
Building Commands
# Build module for running kernel
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
# Build for specific kernel
make -C /path/to/kernel/source M=$(pwd) modules
# Clean build artifacts
make -C /lib/modules/$(uname -r)/build M=$(pwd) clean
# Install module
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install
# Build with verbose output
make -C /lib/modules/$(uname -r)/build M=$(pwd) V=1 modules
Directory Structure
mymodule/
├── Makefile # Kbuild Makefile
├── Kbuild # Alternative to Makefile (preferred for complex builds)
├── mymodule.c # Main source
├── mymodule.h # Header file
└── include/ # Additional headers
└── mymodule_priv.h
Kbuild File (Alternative)
For complex modules, use a separate Kbuild file:
# Kbuild
obj-m := mymodule.o
mymodule-y := main.o utils.o
ccflags-y := -I$(src)/include
# Makefile
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
Cross-Compilation
# ARM module
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- \
-C /path/to/kernel M=$(pwd) modules
# ARM64 module
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
-C /path/to/kernel M=$(pwd) modules
Module Versioning
# Force module version check
MODVERSION := 1
# Skip version check (not recommended)
# CONFIG_MODVERSIONS=n in kernel config
Debugging Build Issues
# Show make commands
make V=1 -C /lib/modules/$(uname -r)/build M=$(pwd) modules
# Check kernel config
cat /lib/modules/$(uname -r)/build/.config | grep CONFIG_MODULES
# Verify kernel headers installed
ls /lib/modules/$(uname -r)/build/include/linux/module.h
Common Errors
| Error | Cause | Fix |
|---|---|---|
KERNELRELEASE not set |
Wrong make invocation | Use make -C ... M=... |
Module.symvers missing |
No kernel build dir | Install kernel-headers |
Unknown symbol |
Missing dependency | Add depends in modinfo |
Version magic mismatch |
Wrong kernel version | Rebuild for target kernel |