Hello World: Writing Your First Kernel Module

Writing and loading a kernel module is a rite of passage in the Linux development world. It allows you to interact with the kernel and the hardware directly. In this guide, we'll walk through the step-by-step process of creating a simple "Hello World" kernel module. Let’s dive in!

Prerequisites

Before we start, ensure you have the following:

  • A Linux environment (Ubuntu or any other distribution will work).
  • Kernel headers installed (for compiling your module).
  • Basic knowledge of using the terminal.
  • A text editor like vim, nano, or any GUI-based editor.

To install the kernel headers on Ubuntu, use the following command:

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

Now that we're all set, let’s create our first module!

Step 1: Setting Up Your Module

Create a new directory for your kernel module:

mkdir hello_world_module
cd hello_world_module

Inside this directory, create a file named hello_world.c. This file will contain our kernel module code.

touch hello_world.c

Next, open the file with your favorite text editor:

nano hello_world.c

Now, let’s start coding!

Step 2: Writing Your Kernel Module

In the hello_world.c file, add the following code:

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

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

void cleanup_module(void) {
    printk(KERN_INFO "Goodbye, World!\n");
}

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

Code Explanation:

  • Include Statements: We include the necessary headers for module development.

  • MODULE_LICENSE: This macro specifies the license of the module. Using "GPL" informs the kernel that this module can be used for kernel development.

  • MODULE_AUTHOR and MODULE_DESCRIPTION: These macros are used for documentation purposes; you can put your name and a brief description of the module.

  • init_module: This function is called when your module is loaded into the kernel. It’s where we place our initialization code.

  • cleanup_module: This function is called when the module is removed from the kernel. Here, you can clean up resources or log your exit.

  • printk: A logging function for the kernel. It works like printf in user-space programming and is used here to output messages to the kernel log.

Step 3: Creating a Makefile

To compile your kernel module, you need to create a Makefile. This file instructs the build system on how to compile the code.

Create a Makefile in the same directory:

touch Makefile

Then open the Makefile in your text editor:

nano Makefile

Add the following content to the Makefile:

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

Makefile Explanation:

  • obj-m += hello_world.o: This line tells the kernel build system that we want to build hello_world.o as a module.

  • all: This target calls the kernel’s build system to compile the module.

  • clean: This target is used to clean up the compiled files.

Step 4: Compiling Your Kernel Module

Now that we have our code and Makefile ready, it’s time to compile the kernel module!

In your terminal, run the following command:

make

If everything goes well, you should see a file named hello_world.ko created in your directory. This .ko file is your compiled kernel module.

Step 5: Loading Your Kernel Module

To load your kernel module into the kernel, use the insmod command:

sudo insmod hello_world.ko

You can check if the module was loaded successfully by using:

lsmod | grep hello_world

You can also view the kernel messages to see the output of our printk statement:

dmesg | tail -n 10

You should see the message Hello, World! reflected in the output.

Step 6: Unloading Your Kernel Module

To unload the module when you’re done testing, use the rmmod command:

sudo rmmod hello_world

Again, confirm that the module has been removed:

lsmod | grep hello_world

And check the kernel messages again:

dmesg | tail -n 10

You should see Goodbye, World! indicating that the cleanup function was successfully executed.

Step 7: Cleaning Up

After you finish working with your module, you may want to delete any compiled files. Run:

make clean

This will remove the compiled .o and .ko files, keeping your directory tidy.

Conclusion

Congratulations! You’ve successfully written, compiled, loaded, and unloaded your very first Linux kernel module. The "Hello World" module serves as a simple introduction to kernel module programming and gives you a taste of how you can interface directly with the Linux kernel.

As you continue your journey into the world of Linux kernel development, there’s a vast array of functionality you can explore, from handling device drivers to implementing system calls and beyond. Keep experimenting, learning, and breaking things to further your understanding of the Linux kernel.

Happy coding, and welcome to the exciting world of Linux kernel development!