Linux Loadable Kernel Module (Sample code)

Kernel modules are piece of code, that can be loaded and unloaded from kernel on demand.

If you want to add code to a Linux kernel, the most basic way to do that is to add some source files to the kernel source tree and recompile the kernel. In fact, the kernel configuration process consists mainly of choosing which files to include in the kernel to be compiled.

But you can also add code to the Linux kernel while it is running. A chunk of code that you add in this way is called a loadable kernel module. These modules can do lots of things, but they typically are one of three things:

1) device drivers  2) file-system drivers  3) system calls.

The kernel isolates certain functions, including these, especially well so they don’t have to be intricately wired into the rest of the kernel.

Kernel modules offers an easy way to extend the functionality of the base kernel without having to rebuild or recompile the kernel again. Most of the drivers are implemented as a Linux kernel modules. When those drivers are not needed, we can unload only that specific driver, which will reduce the kernel image size.

The kernel modules will have a .ko extension. On a normal linux system, the kernel modules will reside inside /lib/modules/<kernel_version>/kernel/ directory.

A Simple kernel module

Prerequisites :

Linux headers needs to be installation for kernel module compilation.

For debian based linux :
apt-get install build-essential linux-headers-$(uname -r) gcc
For Centos/Fedora :
yum install kernel-devel
yum install gcc

Source code :

Filename : ji_lkm.c

/* @JI : Sample linux kernel module program */

#include <linux/module.h> // included for all kernel modules
#include <linux/kernel.h> // included for KERN_INFO
#include <linux/init.h> // included for __init and __exit macros

MODULE_LICENSE("GPL");
MODULE_AUTHOR("@JI : Anukul Verma");
MODULE_DESCRIPTION("A Simple kernel module");

static int __init
ji_init(void)
{
 printk(KERN_INFO "@JI : Module insertion completed successfully!\n");
 return 0; // Non-zero return means that the module couldn't be loaded.
}

static void __exit
ji_cleanup(void)
{
 printk(KERN_INFO "@JI : Cleaning up module....\n");
}

module_init(ji_init);
module_exit(ji_cleanup);

When a module is inserted into the kernel, the module_init macro will be invoked, which will call the function ji_init.

Similarly, when the module is removed, module_exit macro will be invoked, which will call the ji_exit.

Filename : Makefile

obj-m += ji_lkm.o

all:
 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

 

Warning: All kernel modules will operate on kernel space, a highly privileged mode.
So be careful with what you write in a kernel module.

 

Compilation

[root@verma first_module]#
[root@verma first_module]# ls
ji_lkm.c Makefile
[root@verma first_module]#
[root@verma first_module]#
[root@verma first_module]#
[root@verma first_module]# make
make -C /lib/modules/3.10.0-327.36.3.el7.x86_64/build M=/home/first_module modules
make[1]: Entering directory `/usr/src/kernels/3.10.0-327.36.3.el7.x86_64'
 CC [M] /home/first_module/ji_lkm.o
 Building modules, stage 2.
 MODPOST 1 modules
 CC /home/first_module/ji_lkm.mod.o
 LD [M] /home/first_module/ji_lkm.ko
make[1]: Leaving directory `/usr/src/kernels/3.10.0-327.36.3.el7.x86_64'
[root@verma first_module]#
[root@verma first_module]#
[root@verma first_module]#
[root@verma first_module]# ls
ji_lkm.c ji_lkm.ko ji_lkm.mod.c ji_lkm.mod.o ji_lkm.o Makefile modules.order Module.symvers
[root@verma first_module]#
[root@verma first_module]#
[root@verma first_module]#

 

Utilities to Manipulate Kernel Modules

modinfo – Display Module Info

modinfo command will display information about a kernel module.

[root@verma first_module]# modinfo ji_lkm.ko
filename: /home/first_module/ji_lkm.ko
description: A Simple kernel module
author: @JI : Anukul Verma
license: GPL
rhelversion: 7.2
srcversion: 3536AEE65AE7DA5C2A50063
depends:
vermagic: 3.10.0-327.36.3.el7.x86_64 SMP mod_unload modversions

 

lsmod : List Modules that Loaded Already

By reading file /proc/modules

[root@verma first_module]# lsmod
Module   Size    Used by
ppdev    17671    0
pcspkr   12718    2

 

insmod – Insert Module into Kernel

insmod command will insert a new module into the kernel.

[root@verma first_module]# lsmod | grep ji_lkm
[root@verma first_module]#
[root@verma first_module]# insmod ji_lkm.ko
[root@verma first_module]#
[root@verma first_module]# lsmod | grep ji_lkm
ji_lkm 12425 0
[root@verma first_module]#

Using dmesg command, we can see the output from the sample Kernel module. /var/log/messages will also contain outputs.

[root@verma first_module]#
[root@verma first_module]# dmesg | tail -1
[ 3097.016528] @JI : Module insertion completed successfully!
[root@verma first_module]#
[root@verma first_module]#
[root@verma first_module]# tail -l /var/log/messages
Dec  7 14:10:37 verma kernel: @JI : Module insertion completed successfully!
[root@verma first_module]#

 

rmmod – Remove Module from Kernel

rmmod command will remove a module from the kernel. You cannot remove a module which is used by any program.

[root@verma first_module]#
[root@verma first_module]# lsmod | grep ji
ji_lkm 12425 0
[root@verma first_module]#
[root@verma first_module]# rmmod ji_lkm
[root@verma first_module]#
[root@verma first_module]# lsmod | grep ji
[root@verma first_module]#
[root@verma first_module]#
[root@verma first_module]# dmesg | tail -1
[ 3698.530603] @JI : Cleaning up module....
[root@verma first_module]#
[root@verma first_module]#

 

“rmmod -f “ can be used to remove a module forcefully.

Advertisements

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s