Linux Kernel (The Queen of OpenSource) and Its Modules (Part-1)

Surbhit Awasthi
6 min readOct 18, 2020
Source: Wikipedia

What is Linux Kernel?

First let us understand what is a kernel. So, from the smallest of the computers (probably in an IoT device) to the largest of the supercomputers, there are multiple hardware resources that needs to be properly managed, because every piece of software that runs on a computer system fights for the available resources in order to complete its job. Kernel is the piece of software that does this resource management for us, it is the core part of an Operating System.

Now as we understand that kernel is a software, it would be easy to stretch your imagination that there are many kernels available in the market, as is the case with any other piece of software. Linux kernel is one of the most famous kernel out there, its popularity can be understood by the fact that its presence spans from tiny IoT device to the International Space Station. (If you are using an android phone, you too are carrying a linux kernel in your pocket).

Photo by Michael Dziedzic on Unsplash
Source: Wikipedia

Kernel manages the CPU resources, memory resources, processes on any computer, it also comprise of device drivers which are used to communicate with external resources like Universal Serial Buses, Network Interface Cards, et cetera. Kernel is also referred to as the first layer which interacts directly with the hardware and has the highest privileges a software can have in a system (unless we are talking about a co-designed VM, which is a topic for another post).

The kernel is the centre of everything you computer system does, you read a text document, play a game, use WIFI, send email, even when you close an application its the kernel because of which you are able to do that. I hope by now you must have understood how complex this piece of software is. It is said there are 15M lines of code in the Linux Kernel. This is due to such varied usage of environments it works in. The linux kernel being open source can be tweaked in different ways to satisfy needs of different types of systems. Taking our discussion further there are two type of kernel: (I have tried to keep their explanation a bit abstract)

Source: Wikipedia
  1. Monolithic Kernel: All the logic of memory management, CPU management, networking, scheduling et cetera is under one memory space. This memory space is accessible only by kernel and is part of the kernel.
  2. Micro Kernel: With micro kernels, kernel itself uses a very small piece of memory space, and other management system such as networking drivers, et cetera run as user level programs, the kernel communicates with these programs to complete its tasks.

The advantage of micro kernels over monolithic once is that if one of the management programs crash, the kernel itself does not crash. Moreover it is easy to add in new management modules into the system because the kernel need not to be recompiled just to accommodate a new piece of software.

On the other hand if something needs to be added into a monolithic kernel, for example a new TCP connection algorithm for an internal data centre, a monolithic kernel need to be recompiled with the new code, we also have the overhead to find all points in the kernel where previous implementation of TCP was declared. To overcome this issue linux kernel came with the idea of Kernel Module (Linux Kernel Modules (LKM)).

What exactly is a kernel module? Modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. For example, one type of module is the device driver, which allows the kernel to access hardware connected to the system. Without modules, we would have to build monolithic kernels and add new functionality directly into the kernel image. Besides having larger kernels, this has the disadvantage of requiring us to rebuild and reboot the kernel every time we want new functionality.

As we now have the background regarding kernel, we understand that it is the interface between hardware and software, this means we can create device drivers for hardware that does not actually exists (Virtual Hardware, Voilà!). Since we can code a kernel module we can add functionality to the linux kernel and contribute to it.

To try out this idea, I googled and read about how to create a kernel module, after few hours of research I had a basic idea of how to create a module, but adding module to your kernel directly is a dangerous thing because of linux kernel’s monolithic nature. I came across these lines which I feels lay the ground work of how dangerous it could be:

So, you want to write a kernel module. You know C, you’ve written a few normal programs to run as processes, and now you want to get to where the real action is, to where a single wild pointer can wipe out your file system and a core dump means a reboot.

After hours of system restarts, I was able to create a virtual device which I could write to and read from.

This was the code I came up with:

Please run the code at your own risk, because I am still in the learning phase. To run this code follow these instruction:

1. Environment:
- Ubuntu 20.04
- GNU Make 4.2.1
- Linux Kernel: 5.4.0-51-generic
2. Open a terminal session, run the following command as root:
~# tail -f /var/log/kern.log
Keep this terminal window aside, and look at the changes in there when you run the following commands.
(You can close this by pressing Ctrl + C, once done with all steps.)
3. Copy the files in a directory. cd into itRun the following commands as root:~# make
~# insmod code.ko
~# mknod /dev/demovirtualdevice c <number> 0
(the <number> can be found in the terminal session running `tail -f /var/log/kern.log`)
~# gcc test.c -o test
~# ./test
Follow the instruction as test executes, try to read from and write to the device, once satisfied with this contribution to the linux kernel, unload the module from the kernel
~# rmmod code

So this was a basic run down on how you can create a virtual device of your own in the system, remember this is a device driver and since it is directly appended to the kernel it runs with the highest privileges.

This is the point where the fun actually start in building kernel modules, stay tuned for part two where I would like to take our kernel module a step further and try tinkering with user permissions, system calls, root access, and will explore more of this newly bestowed power. Also in the next article I will explain what the above C code does, because it sure look like C but doesn't feels like.

We are running in a fully privileged mode this thought really baffles my mind. More on this in Part-2.

Peace. ✌️

--

--