Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 838 of 93611. Introduction to Embedded LinuxFree lesson

Compiling Modules with the Kernel Build System

Learners will create a Makefile that interfaces with the Linux kernel build system to transform source code into a loadable kernel object.

Compiling Modules with the Kernel Build System

In this lesson, you will learn how to leverage the kbuild system to transform your C source code into a loadable Linux kernel object (.ko file).

When developing kernel modules, you cannot simply use a standard gcc command with typical flags. The kernel is highly dependent on specific configuration settings and header versions; attempting to compile against your host machine's generic libraries will result in "Invalid module format" errors. Instead, we use the Linux kernel's integrated build system, known as kbuild.

The Anatomy of a Module Makefile

To interface with kbuild, you must provide a Makefile that tells the kernel build system where to find the source and how to process it. Unlike a standard application Makefile, this file acts as a bridge to the existing kernel build infrastructure.

Consider this minimal Makefile for a module named my_driver.ko:

obj-m += my_driver.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

How it Works

  1. obj-m: This variable tells kbuild that my_driver.o is a module to be built. Kbuild automatically knows to look for a corresponding my_driver.c file.
  2. -C: This flag switches the working directory to the kernel source tree or the headers directory installed on your system (located at /lib/modules/$(shell uname -r)/build).
  3. M=$(PWD): This critical flag tells kbuild that the actual source code is located in your current working directory, not within the main kernel tree.
  4. modules: This is the target passed to the kernel build system, instructing it to perform the compilation process specific to external modules.

When you run make, kbuild parses your environment, checks your kernel configuration, and invokes the correct compiler with the exact flags required by your specific kernel version. The output is a .ko file, which is a specialized ELF object ready to be inserted into the kernel using insmod. By following this standard, your module ensures compatibility with the exact kernel currently running on your target hardware.

Key Takeaway: Always use the kbuild infrastructure via -C and M=$(PWD) to ensure your module is compiled with the exact configuration and architecture-specific flags required by the target kernel.