About The Linux Kernel Modules Series
As part of my research I had a number of situations where the Linux Kernel's functionality was just not enough. Thankfully, the developers foresaw these situations and thus we got the chance to extend the kernel using kernel modules. Kernel modules are relatively straightforward to write once you get the hang of it. Even though the kernel writing process has barely changed since 2007 when this guide was published. The kernels have advanced a bit and I am planning to give a new, updated and summarised version in the following.
Before you start
Kernel Development can be difficult and error-prone. Bugs are not easy to catch as a lot of the debugging tools are only available in user-space land. Moreover, catching and fixing bugs in the kernel takes more time as often a bug could mean an OS crash.
While useful in some cases, getting things right in the krenel-space land
can be more trouble than it is worth.
So, if you plan on doing kernel development for any other reason than sheer
curiosity, I advise you to first consider whether there is not a more suitable
user-space alternative that can be used.
For example, some network transport protocol extensions only used to work
for TCP and were best designed in the kernel.
However, many of these proposals can now be implemented in QUIC.
QUIC is network transport protocol and can often be used to achieve
similar tasks as TCP.
QUIC has been accepted as an IETF standard with
RFC 9000 in 2021.
Introduction
In this article I will cover the basics of what a kernel module is, how to write a kernel module, how to compile a kernel module, how to load and unload kernel modules. Before I finish the article I will a few more advanced notes and real examples, based on my work. I plan to revisit that section before the conclusion and may eventually create a follow-up article based on the content of that section if it becomes big enough to live as a standalone article.
What Is a Kernel Module
A kernel module is a piece of software that interacts directly with the core Operating System components and is executed directly into the kernel-space. This means that some basic operations such as division or outputting text to the standard output are performed differently.
Writing Your First Kernel Module
Disclaimer:
When working with kernel modules, or any other piece of software that
runs in the kernel-land, any unintended behaviour could result in a
segmentation faults and stack overflows.
This could leave your machine in a corrupted state that will require a
reboot or reformatting of the operating system.
I recommend that at all times during development you use a virtual machine to
avoid accidentally corrupting your main operating system.
The writing part of creating a kernel module is relatively easy, perhaps the easiest thing in the process. To write a kernel module, you need to:
- Import the correct headers
- Write your kernel code
- Apply the relevant API hooks and link your module with the operating system, or otherwise make the host OS aware of how to use your module
TODO
Let us look at the specific pieces of the code and see how they relate to the steps above.
TODONow, let us save that module in a directory of your choice, I will save it to /home/mihail/kernel-dev-example/my_module.c. Next, we will look at how to compile the code we just saved.
Compiling Your First Kernel Module
To compile a kernel module, TODO
Using Your First Kernel Module
Loading Your Kernel Module
To load a kernel module TODO
Unloading Your Kernel Module
Introducing Changes to Your Kernel Module
Advanced Examples
Final Words
That is it... Thanks for following along, and I hope I have helped you in your first kernel module writing journey. The kernel module that we did here is not particularly useful but I hope I managed to demystify the basics of the process a bit. For more advanced example, take a look at the complete tutorial here. If I can find the time: I pledge to write an advanced guide that takes a look at extending the TCP stack.