LWM-Linux/11 - Linux Kernel and Modules/Building and Installing Kernel Modules.md

4.0 KiB

Building and Installing Linux Kernel Modules:

1. Introduction to Kernel Modules

Kernel modules are pieces of code that can be dynamically loaded and unloaded into the running kernel. They extend the functionality of the kernel without requiring a system reboot. This guide will walk you through the process of writing, building, and installing a simple kernel module.

2. Prerequisites

  • A Linux system with kernel headers installed
  • Basic knowledge of C programming
  • GCC compiler
  • Make utility

To install kernel headers on Ubuntu/Debian:

sudo apt-get install linux-headers-$(uname -r)

On CentOS/RHEL:

sudo yum install kernel-devel

3. Writing a Simple Kernel Module

Let's create a basic "Hello World" kernel module. Create a file named hello.c:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple Hello World module");
MODULE_VERSION("0.1");

static int __init hello_init(void) {
    printk(KERN_INFO "Hello, World!\n");
    return 0;
}

static void __exit hello_exit(void) {
    printk(KERN_INFO "Goodbye, World!\n");
}

module_init(hello_init);
module_exit(hello_exit);

4. Creating a Makefile

Create a Makefile in the same directory:

obj-m += hello.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

5. Building the Kernel Module

To build the module, run:

make

This will compile your module and create a hello.ko file.

6. Loading and Unloading the Module

To load the module:

sudo insmod hello.ko

To unload the module:

sudo rmmod hello

To view kernel messages:

dmesg | tail

7. Automatically Loading Modules at Boot

To load your module at boot time:

    1. Copy the module to the kernel modules directory:
sudo cp hello.ko /lib/modules/$(uname -r)/
    1. Update the module dependencies:
sudo depmod
    1. Add the module name to /etc/modules:
echo "hello" | sudo tee -a /etc/modules

8. Module Parameters

You can add parameters to your module for runtime configuration. Modify hello.c:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple Hello World module with parameters");
MODULE_VERSION("0.2");

static char *name = "world";
module_param(name, charp, 0644);
MODULE_PARM_DESC(name, "The name to display in /var/log/kern.log");

static int times = 1;
module_param(times, int, 0644);
MODULE_PARM_DESC(times, "The number of times to display the name");

static int __init hello_init(void) {
    int i;
    for (i = 0; i < times; i++) {
        printk(KERN_INFO "Hello, %s!\n", name);
    }
    return 0;
}

static void __exit hello_exit(void) {
    printk(KERN_INFO "Goodbye, %s!\n", name);
}

module_init(hello_init);
module_exit(hello_exit);

Now you can pass parameters when loading the module:

sudo insmod hello.ko name="Alice" times=3

9. Debugging Kernel Modules

For debugging, you can use:

  • printk() for logging (view with dmesg)
  • Kernel's EXPORT_SYMBOL macro to expose symbols for debugging
  • Kernel's built-in debugger (KDB) or KGDB for remote debugging

10. Best Practices

  • Always check return values of kernel functions
  • Use appropriate locking mechanisms for shared resources
  • Follow kernel coding style (run scripts/checkpatch.pl on your code)
  • Be cautious with memory allocation and deallocation

11. Distribution and Maintenance

  • Keep your module updated with kernel changes
  • Document your module thoroughly
  • Consider submitting your module to the mainline kernel if it's widely useful

This guide covers the basics of kernel module development. As you advance, you'll want to explore more complex topics like device drivers, sysfs interfaces, and kernel APIs specific to your module's functionality.