Writing a simple kernel module

Writing kernel modules are a great way to interact with kernel.

Getting started

For listing all the kernel modules in the system, use:

lsmod

It lists three fields: name,size and where the module is used.

Below is the C program that I used simple-mod.c

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

int simple_init(void)
{
  printk(KERN_INFO "Loading Module\n");
  return 0;
}

void simple_exit(void)
{
  printk(KERN_INFO "Removing Module\n");
}

module_init(simple_init);
module_exit(simple_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("DB");

Breakdown of the program.

Including external libraries

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

Functions

int simple_init(void)
{
  printk(KERN_INFO "Loading Module\n");
  return 0;
}

void simple_exit(void)
{
  printk(KERN_INFO "Removing Module\n");
}
  • Two functions simple_init and simple_exit which will be called by module_init and module_exit respectively. More on these later.
  • People familiar with c programming would notice that we are using printk instead of printf. printk() is kernel equivalent of printf().
  • printk logs output to kernel buffer which can be read by dmesg command.
  • KERN_INFO is a priority flag which can be specified with printk(). KERN_INFO is used for informational messages.

Module entry/exit point

module_init(simple_init);
module_exit(simple_exit);
  • module_init() is the module entry point, meaning this will be invoked each time when the module is loaded into the kernel.
  • module_exit() will be called when the module is removed from the kernel.

Standard Practice

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("DB");

These are just informational messages and program does not depend on this. But its a good idea to include this as its standard practice in developing kernel modules.

This C program should be compiled using Makefile. We can compile the module by

make

This produces several files, like this

# ls
Makefile  modules.order  Module.symvers  simple-mod.c  simple-mod.ko  simple-mod.mod.c  simple-mod.mod.o  simple-mod.o

The file we are interested in is simple-mod.ko, this is the compiled kernel module. To insert this into kernel, use

sudo insmod simple-mod.ko

List all the modules and verify that our module is present in the list.

# lsmod | grep simple
simple_mod             12498  0

dmesg command should output something like this,

# dmesg
[15377.756242] Loading Module

Cool huh! :)

We can remove the module by

sudo rmmod simple-mod.ko

Checking dmesg again,

# dmesg
[15377.756242] Loading Module
[15609.855652] Removing Module

Tip:

  • To make dmesg timestamp human readable use dmesg -T

This is a teeny-tiny introduction to kernel modules. One of the areas that requires more exploration is Makefile.

This post was heavily inspired by the book Operating System Concepts