What is kernel?
Kernel is nothing but the core of any operating system. It is the kernel that makes an OS entirely different from others. A kernel is actually a large block of code which keeps the system up and running from the time of booting, till shutdown. Kernel is that part of an OS which directly communicates with the hardware of the machine in which it runs and also with external hardware devices.
The kernel can be viewed as resource managing code of an OS. It is responsible for managing and allocating resources like memory, processors etc. It also allows OS to communicate and control various external hardware devices like pendrive, memory card, keyboard etc.
User program Vs Kernel program:
User program or applications runs in a memory area called “user space”. The kernel program runs in another memory area called “kernel space”. Kernel program always runs in a supper access mode. So from programming point of view, kernel programming means power to access anything and everything in a system.
Why kernel programming:
Through kernel programming we can access or control the basic subsystems of kernel like, scheduling, memory management, file system management, networking management, inter-process communication etc. We can develop separate kernel modules which can be inserted into the kernel while the system is running.
The most attractive part of the kernel programming is device driver coding, through which we can interface various external hardware devices like USB, disk drives, data card or any other latest peripheral devices in the market.
Importance of Kernel in an OS
Importance of kernel in an OS:
Let us talk about the Linux kernel only. The basic architecture of an OS can be viewed as a layered structure.
Fig. 1: Image Showing Basic Architecture of an OS
From the above figure it is clear that the innermost layer is the system hardware, and the user applications communicate with the hardware through the kernel layer.
System call interface:
User space – This is the memory area in which user applications runs.
Kernel space – This is the memory area in which the kernel program runs.
Fig. 2: Image showing System Call Interfaces
The system call interface forms a layer between the user space and kernel space. It is the only mechanism through which the user space applications can access the kernel resources.
Fig. 3: Image showing System Call Interface between Kernel and User Space
The fundamental architecture of the GNU/Linux operating system:
Fig. 4: Image showing Architecture of Linux Operating System
Linux Kernel Subsystems
The linux kernel subsystems:
The linux kernel is conceptually divided into several subsystems like,
1) Process management subsystem
2) Memory management subsystem
3) File management subsystem
4) Inter process communication subsystem
5) Network management subsystem
6) Device driver subsystem
Fig. 5: Image showing Linux Kernel Sub Systems
1) Process Management:
Process management subsystem interacts directly with all other subsystems of the kernel. Its purpose is to schedule and control various process. It is responsible for multiprocessing or multitasking. Each process is broken down to units called “threads” and run those threads from various processes at a very high speed, so that the user feels like all the applications are running simultaneously.
2) Memory Management:
This subsystem is responsible for managing the physical memory. It provides functions like, memory mapping, shared virtual memory, swapping etc. Virtual memory is provided for the user applications by swapping in and out the applications with the RAM and swap space in Disk drive, so that the running application feel that it is having lot more memory available in RAM than it actually dose.
3) File system Management:
Linux supports various kinds of file systems. The responsibility of the subsystem is to manage the files. All the kernel modules interact with this subsystem. It also interacts with device drivers forming a virtual file called device file. Both the kernel and the hardware can read into or read from the device file. Thus it forms an interface between kernel and actual hardware.
4) Inter-Process Communication:
The Inter-Process Communication (IPC) subsystem provides a means, and controls the communication between various processes. The IPC is achieved through different mechanisms like Socket, Pipe, and Shared Memory etc.
5) Network Interface:
The network interface subsystem provides network access to the linux machine. It supports various protocols like TCP, UDP, IPV4, IPV6 etc. This subsystem directly interacts with network device driver.
6) Device driver:
A device driver is a specific code written for accessing and controlling a particular kind of device. It forms a device file through which the user applications can access the device just like accessing a file. So the application developers can do their coding without need to know the hardware details. We generally don’t consider the code for accessing the CPU and Physical memory by the kernel as device drivers even though they also form the hardware interface part of an OS. The device driver code alone forms the largest part of the kernel. The device driver subsystem is again divided into character driver, block driver, network driver etc.
Important codes for the subsystems
Where can we find important piece of codes for these subsystems?
DEVICE DRIVER ———————————————————————————————————–/drivers
Character device driver —————————————————-/drivers/char
Block device driver ———————————————————-/driver/block
Network device driver ——————————————————/driver/net
FILE SYSTEM MANAGEMENT —————————————————————————————–/fs
Various kernel modules —————————————————-/modules
INTER PROCESS COMMUNICATION ———————————————————— ——————–/ipc
Shared memory IPC ————————————————————————————- |
Signal IPC ————————————————————————————————— |
System V IPC ———————————————————————————————–|—/ipc
Pipe IPC —————————————————————————————————– |
IPC manager ———————————————————————————————– |
Message queue manager ——————————————————————————-|
MEMORY MANAGEMENT ————————————————————————————————/mm
Shared virtual memory ————————————————————/mm/shmem.c
Memory mapper ——————————————————————–/mm/mmap.c
Demand pager ———————————————————————–/mm
Memory manager ——————————————————————-/mm
NETWORK MANAGEMENT ———————————————————————————————-/net
Network protocol devices ———————————————————————–|_ _ /net
Network device manager ————————————————————————|
PROCESS MANAGEMENT ———————————————————————————————–/kernel
Task queue ——————————————————————————/kernel
Architectural specific scheduler —————————————————-/arch/i386/kernel/process.c
Modules can be considered as parts of kernel code. A module never runs by itself, but can be loaded or removed into the kernel while the system is running. Once a module is loaded into the kernel, it behaves like a part of the actual kernel itself. The kernel modules are mainly used to load device drivers. Suppose we have plugged in a USB device, now the kernel will search for the appropriate driver module and load it immediately.
A kernel module basically has two necessary functions, ‘init_module ()’ and ‘cleanup_module ()’ which are linked to the ‘init’ and ‘exit’ respectively. When a module get inserted, the ‘init_module ()’ is executed and when the module get removed the ‘cleanup_module ()’ is executed. The following picture gives an overview of the module loading and unloading details
Fig. 6: Image showing Kernel Modules in Linux
Hello World Kernel Module
Hello Word Kernel module:
Let’s try out a simple kernel program. As always we start with “hello world” here also.
We are going to edit a kernel module, ‘make’ it and insert it.
At first create a folder and name it. Make sure that the parent folders or the folder itself does not have white spaces in their folder name. Open any text editor, VI or VIM and edit the following code. Save the code as “hello_world.c”.
int init_module (void)
printk ( “nHELLO WORLDn” );
void cleanup_module (void)
printk ( “nGOOD BYEn” );
The ‘printk ()’ is the kernel equivalent of ‘printf ()’ in user-space programming.
Now we need to ‘make’ the code using gcc compiler and for that we use the “make” command. We need a file called “Makefile” in order to make the .c file in the same folder.
Create a file having the following contents and save it as “Makefile” for our hello_world.c
obj-m += hello_world.o
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
Now open the terminal in that folder and type “make” and then enter.
If the make was successful then a number of files get generated in the folder. Among those files, there will be a ‘hello_world.ko’ file. The ‘.ko’ represents Kernel Object.
We can manually insert the kernel module using the command “insmod”. Type the following in the terminal and press enter.
Now we know that the ‘init_module’ might have been executed while we inserted the module. Let’s see if the message has been printed or not. Type the following command in the terminal and press enter.
You can see a lot of message printed so far by other modules and at the very bottom we can find our message also.
Ok, now you have your first kernel program executed successfully. If you want to see your module listed along with other modules, type the following command in the terminal and press enter.
If you’ve done with your module, it should be removed so as to free the resource and to avoid unexpected errors. Type the following command in the terminal and press enter.
Now try ‘dmesg –c’ ones more to find the message printed by the ‘cleanup_module ()’. Try ‘lsmod’ also to check whether the module is removed from the list of loaded modules.