What are Kernel Modules?
In the realm of operating systems, particularly Unix-like systems such as Linux, a kernel module is a piece of code that can be loaded into and unloaded from the kernel on demand. Kernel modules extend the functionality of the kernel, without requiring a system reboot to apply changes.
This dynamic loading capability is crucial for modern operating systems, allowing for flexibility and efficient resource management. Instead of having every possible driver or feature compiled directly into the main kernel image (a monolithic kernel), many of these components are implemented as loadable kernel modules (LKMs).
Why Use Kernel Modules?
- Flexibility: New hardware support or features can be added without recompiling the entire kernel.
- Modularity: The kernel remains smaller, with only essential components compiled in. Unused functionality doesn't consume memory.
- Development: Modules can be developed and tested more independently, speeding up the development cycle.
- Resource Management: Modules can be loaded only when needed and unloaded when no longer required, freeing up system resources.
How Kernel Modules Work
Kernel modules are typically dynamically linked libraries that contain kernel code. When the system needs to support a new piece of hardware (like a network card or a USB device) or enable a specific feature (like a new filesystem), the corresponding module can be loaded. Conversely, if a module is no longer in use, it can be unloaded.
Key Concepts
- Loading: Modules are loaded using utilities like
insmodormodprobe.modprobeis generally preferred as it handles dependencies between modules. - Unloading: Modules can be removed using
rmmodormodprobe -r. - Dependencies: A module might depend on other modules.
modprobeautomatically loads any required dependencies. - Module Parameters: Modules can accept parameters that allow customization of their behavior at load time.
A Simple Example: The "Hello, World!" Module
Let's look at a minimal kernel module to illustrate the basic structure. This module simply prints a message to the kernel log when loaded and another when unloaded.
hello_module.c
// SPDX-License-Identifier: GPL-2.0
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init(void)
{
pr_info("Hello, Kernel Modules! (<%s>)\n", __FUNCTION__);
return 0; // Success
}
static void __exit hello_exit(void)
{
pr_info("Goodbye, Kernel Modules! (<%s>)\n", __FUNCTION__);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple hello world kernel module");
MODULE_VERSION("0.1");
Explanation:
#include <linux/init.h>: Provides the__initand__exitmacros.#include <linux/module.h>: Essential for all kernel modules.#include <linux/kernel.h>: Provides kernel functions likepr_info.hello_init(): This function is marked with__init, indicating it's an initialization function called when the module is loaded.pr_infois used to print messages to the kernel log (viewable withdmesg).hello_exit(): This function is marked with__exitand is called when the module is unloaded.module_init(hello_init);: Registers thehello_initfunction as the module's entry point.module_exit(hello_exit);: Registers thehello_exitfunction as the module's exit point.MODULE_LICENSE("GPL");: Specifies the license of the module. This is important for kernel compatibility.MODULE_AUTHOR(...),MODULE_DESCRIPTION(...),MODULE_VERSION(...): Metadata about the module.
Compiling and Loading
To compile a kernel module, you typically need a Makefile and the kernel's build system. A simple Makefile for the above module might look like this:
Makefile
obj-m += hello_module.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
After creating both files, you would compile with make. This generates hello_module.ko (the kernel object file).
To load it (as root):
sudo insmod hello_module.ko
And to check the output:
dmesg | tail
To unload it (as root):
sudo rmmod hello_module
Conclusion
Kernel modules are a fundamental mechanism for extending operating system functionality without requiring reboots. They provide a powerful way to manage hardware, implement new features, and optimize resource usage. Understanding how they work is essential for anyone delving into operating system internals or driver development.
Further Reading: