Go4Expert

Go4Expert (http://www.go4expert.com/)
-   Linux (http://www.go4expert.com/articles/linux/)
-   -   Loadable Kernel Modules (LKMs) in Linux (http://www.go4expert.com/articles/loadable-kernel-modules-lkms-linux-t26795/)

poornaMoksha 27Sep2011 08:39

Loadable Kernel Modules (LKMs) in Linux
 
LKM stands for Loadable kernel modules. This term is mainly used in context with Linux OS. LKMs are independent modules that can be loaded and unloaded to and from kernel. This provides a mechanism through which the functionality of the kernel can be enhanced on run time, without having to recompile the kernel again and again. Other advantage of using LKMs would be since they can be unloaded at run time so they do not add to the size of kernel permanently. Also, no reboot is required to activate an LKM.

How do modules get loaded in Kernel



The binary 'lsmod' lets you see what all modules are already loaded into the kernel. It gives this information by reading /proc/modules.

A module is loaded into kernel by using the binary 'modprobe'. modprobe is passed an argument like 'my_module'(name of the module to load). Next the modeprobe peeks into the file /lib/modules/<version>/modules.dep to see if this module has any dependencies. If yes, then it loads the dependencies in the desired order. Finally modprobe uses insmod to first load any pre-requisites into the kernel and then load the requested module. insmod is intended to be fairly dumb about the location of modules, whereas modprobe is aware of the default location of modules, knows how to figure out the dependencies and load the modules in the right order.So for example, if you wanted to load the 'module_a' module (which is dependent on 'module_b' module), you'd have to either run:

insmod /<CompletePath>/module_b.ko
insmod /<CompletePath>/module_a.ko

or you can directly run :

modprobe module_a

So we see above that insmod requires complete path and also keep track of the order in which modules need to be inserted while using modprobe doesn't require either of the two considerations.

Example



Lets create a simple 'Hello World' LKM :

Code:

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

int init_module(void)
{
        printk(KERN_INFO "Hello world!!!!!.\n");

        /*
        * A non 0 return means init_module failed; module can't be loaded.
        */
        return 1;
}

void cleanup_module(void)
{
        printk(KERN_INFO "Goodbye world!!!!!!.\n");
}

Kernel modules have two basic functions. One that is called when module is loaded (init_module()) while the other that is called when module is unloaded (cleanup_module()). printk() is a logging mechanism for the kernel, it is used to log information or give warnings.

Compiling LKMs



Kernel Modules are compiled a bit differently. Earlier this process used to be a bit complicated while today there is a new way of doing things known as 'kbuild'. See file see file linux/Documentation/kbuild/modules.txt for more information.

lets take a look at a simple makefile for compiling our module :

Quote:

obj-m += lkm.o

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

clean:
sudo make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
For those who are interested in Makefiles, linux/Documentation/kbuild/makefiles.txt is for you!!!!

Here is the out put of the compilation :

~/practice $ make
sudo make -C /lib/modules/2.6.32-21-generic/build M=/home/himanshu/practice modules
make: Entering directory `/usr/src/linux-headers-2.6.32-21-generic'
CC [M] /home/himanshu/practice/lkm.o
Building modules, stage 2.
MODPOST 1 modules
LD [M] /home/himanshu/practice/lkm.ko
make: Leaving directory `/usr/src/linux-headers-2.6.32-21-generic'


Now if we run a utility 'modinfo' over the lkm.ko file. We get :

~/practice $ modinfo lkm.ko
filename: lkm.ko
srcversion: 2192E356BE77823301F684F
depends:
vermagic: 2.6.32.11+drm33.2 SMP mod_unload modversions

So, 'modinfo' provides information about the module.


Now, its time to insert the freshly baked hello world program into the kernel. Here we go :

insmod ./lkm.ko

Now, we remember that there was a function(init_module()) that would have been called as we inserted the module. So lets look out for the print that was given in that function. Use the command 'dmesg' for this :

[ 54.418842] PPP Deflate Compression module registered
[ 585.312063] CE: hpet increasing min_delta_ns to 15000 nsec
[ 6205.434880] lkm: module license 'unspecified' taints kernel.
[ 6205.434884] Disabling lock debugging due to kernel taint
[ 6205.434945] Hello world!!!!!.

Voila, See the last log. Here is our very first LKM working.


Now to remove the module, use command 'rmmod'.

rmmod lkm.ko

Again use 'dmesg' command to look at whether the print in cleanup_module() executed or not. Here is the output of dmesg again :

[ 585.312063] CE: hpet increasing min_delta_ns to 15000 nsec
[ 6205.434880] lkm: module license 'unspecified' taints kernel.
[ 6205.434884] Disabling lock debugging due to kernel taint
[ 6205.434945] Hello world!!!!!.
[ 6576.074983] Goodbye world!!!!!!.


The last line is clearly what was expected. Our module is unloaded successfuly.


As of Linux 2.4, you can rename the init and cleanup functions of your modules; they no longer have to be called init_module() and cleanup_module() respectively. This is done with the module_init() and module_exit() macros. These macros are defined in linux/init.h. See the following example :

Code:

#include <linux/module.h>      /* Needed by all modules */
#include <linux/kernel.h>      /* Needed for KERN_INFO */
#include <linux/init.h>        /* Needed for the macros */

static int lkm_init(void)
{
        printk(KERN_INFO "Hello, world \n");
        return 0;
}

static void lkm_exit(void)
{
        printk(KERN_INFO "Goodbye, world \n");
}

module_init(lkm_init); // here we register our own function(instead of init_module()) which will get called during module init.
module_exit(lkm_exit); // here we register our own function(instead of cleanup_module()) which will get called during module init.

Now after inserting and removing this module using insmod and rmmod. We see the output of dmesg :


[ 7232.873570] Hello, world 2
[ 7238.865014] Goodbye, world 2

Conclusion



Loadable kernel modules is a very powerful feature of linux kernel. It can be used to add to the capabilities of Linux at run time without any need to compile or reboot the whole kernel.

Stay tuned for more!!!


All times are GMT +5.5. The time now is 05:33.