Linux Kernel Module Programming

Abhishek Jaisingh
3 min readJun 13, 2020

--

Modules are pieces of code that can be loaded & unloaded into the kernel on-demand. They can be loaded into the kernel at run-time without the need to reboot the system or rebuilding the kernel itself. This can be very useful for certain use cases like device drivers. Building the source for all types of device drivers would otherwise bloat the kernel, instead, this allows us to dynamically load modules when required.

Listing Currently Installed Kernel Modules

Lets first check what modules are in our machine using lsmod:

❯❯❯ lsmod
Module Size Used by
ppp_deflate 16384 0
bsd_comp 16384 0
...

Under the hood, lsmod just reads this info from the proc filesystem’s modules file

❯❯ cat /proc/modules
btrfs 1253376 0 — Live 0x0000000000000000
zstd_compress 167936 1 btrfs, Live 0x0000000000000000
ufs 81920 0 — Live 0x0000000000000000
...

Hello, (Kernel) World!

Now, let's write our first kernel module which just prints something in kernel logs!

Module Code

We’ll be using a simple Makefile to compile our code:

Makefile

With the two files in place, we can proceed to build our kernel module:

❯❯❯ make

this will generate the built binary named hello.ko

Now, we can proceed to insert the module into our running kernel

NOTE: If you have secure boot enabled, the newer kernels won’t allow inserting arbitrary kernel modules. So, either you can disable secure boot in your BIOS or you need to sign the kernel modules you want to install.

Steps to securely sign your kernel modules:

1. Create a X509 certificate that can be imported in firmware
2. Enrolling the public key just created
3. Sign the module you want to install
4. Install the module

You need to be root to do steps 2 & 4. The detailed process is described in a nice Ubuntu blog.

❯❯❯ sudo insmod ./hello.ko

Since this is a kernel module and not your regular program it won’t produce any output on your terminal as such. But what about the printk statements in our code, where does it output stuff?

printk is a logging mechanism for the kernel, and we can see these messages in the kernel logs using dmesg.

❯❯❯ dmesg | tail -n 4
...
[ 689.218683] hello: loading out-of-tree module taints kernel.
[ 689.219109] Hello, World!

As expected, if we remove the kernel module now, we’ll see cleanup code get executed:

❯❯❯ sudo rmmod hello                                                                                                                                              
❯❯❯ dmesg | tail -n 4
...
[ 689.219109] Hello, World!
[ 1285.507306] Bye World!

Diving Further

Here we just used two hooks / functions that the kernel provides that are executed when the module is loaded and other when the module is removed. The kernel has a lot of hooks that you could play around and build interesting stuff with e.g. you could execute your code when a network packet enters your machine, leaves your machine or is routed through your machine. If you have heard of IPTables / Netfilter this must ring a bell.

Conclusion

This was an introductory article to write your first kernel module, however, this is just the tip of the iceberg. We could do all sorts of interesting stuff with it. The Linux Kernel Module Programming Guide is an excellent place to start if you are interested in exploring this further.

References

  1. The Linux Kernel Module Programming Guide: https://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf

--

--

Abhishek Jaisingh

MBA - IIM Bangalore, Previously SDE II @ Tower Research Capital, IIT Roorkee Computer Science