Sitemap

How to Write a Simple Linux Kernel Module?

3 min readMar 9, 2024

Kernel module development can be challenging. Let’s write our first simple Linux Kernel Module.

Press enter or click to view image in full size
Photo by Filip Zrnzević on Unsplash

Let’s create a directory:

mkdir blog-hello-world-kernel

Place a Makefile in that directory:

obj-m += bloghello.o
PWD := $(CURDIR)
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Place a simple C file:

bloghello.c

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

static int __init construct(void) {
pr_info("First kernel module: Hello World!\n");
return 0;
}

static void __exit destruct(void) {
pr_info("First kernel module has been removed\n");
}

module_init(construct);
module_exit(destruct);

MODULE_LICENSE("GPL");

Let’s build it:

root@main:~/blog-hello-world-kernel# make
make -C /lib/modules/5.11.0-49-generic/build M=/root/blog-hello-world-kernel modules
make[1]: Entering directory '/usr/src/linux-headers-5.11.0-49-generic'
CC [M] /root/blog-hello-world-kernel/bloghello.o
MODPOST /root/blog-hello-world-kernel/Module.symvers
CC [M] /root/blog-hello-world-kernel/bloghello.mod.o
LD [M] /root/blog-hello-world-kernel/bloghello.ko
BTF [M] /root/blog-hello-world-kernel/bloghello.ko
Skipping BTF generation for /root/blog-hello-world-kernel/bloghello.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-5.11.0-49-generic'
root@main:~/blog-hello-world-kernel#

The loadable kernel object has been created:

Press enter or click to view image in full size

You can install the Kernel Object via the insmod command:

insmod bloghello.ko

You can check if it is actually installed via lsmod:

Press enter or click to view image in full size

You can see the module’s output in /var/log/syslog or in the output of dmesg :

Press enter or click to view image in full size

You can uninstall the module via rmmod :

rmmod bloghello

Let’s check dmesg once more:

Press enter or click to view image in full size

Congratulations! You’ve managed to construct your first Linux Kernel module.

You can print messages to different log levels:

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

static int __init construct(void) {
printk(KERN_INFO "INFO Level message\n");
pr_info("Another INFO Level message\n");

printk(KERN_WARNING "WARNING Level message\n");
pr_warn("Another WARNING Level message\n");

printk(KERN_ERR "ERROR Level message\n");
pr_err("Another ERROR Level message\n");

printk(KERN_CONT "This " );
pr_cont("message ");
printk(KERN_CONT "is " );
pr_cont("single ");
printk(KERN_CONT "line\n");

return 0;
}

static void __exit destruct(void) {
printk(KERN_INFO "The module has been removed\n");
}

module_init(construct);
module_exit(destruct);

MODULE_LICENSE("GPL");

Let’s check dmesg :

Press enter or click to view image in full size

You can filter log lines by levels:

--

--

No responses yet