Kernel Module Programming: Tutorial


  

This edition of techblog covers a tutorial that guides you to implement a very simple Linux kernel module in your system. In order to meddle with kernel modules you need to have downloaded the kernel source files from the repository. You can also download this from the official kernel website.  But it is highly recommended that you download the source files provided by your distribution as the total number of driver files in the actual kernel source tree is much higher and your distribution will help you to download  the required driver files alone.

 

Setting up your system

You need to have essential compilers and tools for developing kernel modules. Some of the recommended tools include fakeroot  (which provides a fake root environment), kernel-wedge ( which can split udeb packages). These are required if you are using a Debian based distribution.

Though most of the popular distributions come with compilers like GCC and G++, please check that these are present by issuing the names of the compilers in the terminal (you may get an error message indicating that there was no input file – this means that your compiler is working).

 

In Ubuntu, you can issue:

 

sudo apt-get build-dep –no-install-recommends linux-image-$(uname -r)
sudo apt-get install fakeroot kernel-wedge build-essential makedumpfile kernel-package

 

And this will install all the required packages in your system.

Now you may issue

uname –r

and check the kernel version that you are using.

 linux kernel version - command

 

Writing Our First Module

 

Let’s write a simple module for this tutorial

 

#include <linux/module.h>
MODULE_AUTHOR("PG Aasis Vinayak");
MODULE_LICENSE("GPL GPLv3");
static int start__module(void)
{
     printk("This is a sample module for techblog!\n");
     return 0;
}
static void end__module(void)
{
     printk("From techblog.aasisvinayak.com!\n");
}
module_init(start__module);
module_exit(end__module);

 

You may save this file as sample_module_for_techblog.c. 

The header file module.h is used in order to access some of the functions used in this module. If you look at the code you can comprehend that MODULE_AUTHOR() is used to  send a string for setting the ‘author’ of the module. So is the case with the MODULE_LICENSE() functions.

The next two functions are custom ones. The void (that returns nothing) functions start__module() and end__module()  merely print statements when the kernel module is loaded and unloaded.  The loading and unloading process is handled using the module_init() and module_exit() functions.

In order to compile this file we need to write a simple ‘make file’ and here is the code for the same:

 

obj-m += sample_module_for_techblog.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
clean-files := Module.symvers

 

This will perform all the make and clean processes. And you can compile the kernel module by going to the directory (where the files are located) and issuing the ‘make’ command.

 

compiling kernel modules

 

If you look at the directory you can see that many objects files are generated during the process. And the compiled object sample_module_for_techblog.ko is the one which we are looking for.

You may also see that another C file was generated dynamically during the process. For your reference, here is the code from that file:

 

#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>
MODULE_INFO(vermagic, VERMAGIC_STRING);
struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {
    { 0xec5ba0f9, "module_layout" },
    { 0xb72397d5, "printk" },
};
static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";
MODULE_INFO(srcversion, "C82A57D3876AEF6D3774201");

 

You may have a look at my guest columns that appeared in Linux For You for more details.

 

Loading the Kernel

You can use insmod for loading a kernel module into the main running kernel. You need to be ‘root’ (super user) for doing this. And you can use the rmmod command for removing the kernel module that you have added (loaded into) to the Kernel.

 

loading modules into kernel

 

In the picture shown above, you can see that I have assigned the module to a null device /dev/null (just like a driver). This will cause the module to ‘write to’ this null device when it is loaded and unloaded. And you can see this using ‘dmesg’.

You can also write a complex character device driver and use it for manipulating the contents of the device (I have written about this in one of my columns. Please see the Linux For you website for more information).

Tags: , ,


TechBlog on Facebook

Comments (3)

 

  1. Rahul says:

    Help reqired:

    Sometimes when i run my kernel module, it hangs after sometime.
    We are using a dev file to communicate with a user program…

    PLEASE help!

  2. Admin says:

    are you getting a kernel panic? please send me the code so that i can understand what it does

  3. ritwik says:

    friend this piece of code didnt work .. pls follow this thread to know what the problem is:

    http://superuser.com/questions/374627/unable-to-compile-a-kernel-module/374636#374636

    P.S. I am drunMonk .. and pls help me sort the issue .. and if possible please notify me through e mail when you have fixed the issue :) thanks in advance

Leave a Reply