Writing Your First Kernel Module Programming In Linux

Introduction :

Kernel module is the piece of code which extent the functionality of the linux kernel, without recompiling full kernel and not even doing any reboot.

This kernel module can be loaded and unloaded on demand. Kernel module will not run in user space instead it will run in kernel space.

Initial setup to compile kernel module:

To compile and run kernel module we need to have linux kernel header. Installing linux kernel header will vary on different linux distros.

Below command used to install kernel header for Centos 6.5. This command is same for redhat and fedora and its variant.

yum install kernel-devel

you can see the installed kernel header in /usr/src/kernels directory.



If we want to learn any new programming language we always go for Hello world program. So here i going to explain how to compile and run Hello World kernel module program.

Writing module program is different than user space program. Because in user space C program start at main() but it is not module programming.

There is two function called init_module() and cleanup_module(). This init_module() function will called when module inserted into the kernel. similarly cleanup_module will be called when module unloaded from the kernel. I will demonstrate this later.


hello.c

#include <linux/module.h> /* It used for all modules */
#include <linux/kernel.h> /* It used for KERN_INFO */

int init_module(void) /* Called when insmod */
{
printk (KERN_INFO "Hello World\n");
return 0;
}

void cleanup_module(void) /* Called when rmmod */
{
printk (KERN_INFO "Bye Bye\n");
}

We need to write the make file for making compilation in easy manner


Makefile:

obj-m += hello.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

Now we have written kernel module C program and Makefile for compilation

[root@localhost hello]# ls -l
total 8
-rw-rw-r--. 1 sujin sujin 301 Aug 17 17:08 hello.c
-rw-rw-r--. 1 sujin sujin 156 Aug 17 16:57 Makefile


To compile module program simple run make command in directory where hello.c and Makefile available.

[root@localhost hello]# make
make -C /lib/modules/2.6.32-431.23.3.el6.x86_64/build M=/home/sujin/kernel_dev/module/hello modules
make[1]: Entering directory `/usr/src/kernels/2.6.32-431.23.3.el6.x86_64'
  CC [M]  /home/sujin/kernel_dev/module/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/sujin/kernel_dev/module/hello/hello.mod.o
  LD [M]  /home/sujin/kernel_dev/module/hello/hello.ko.unsigned
  NO SIGN [M] /home/sujin/kernel_dev/module/hello/hello.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.32-431.23.3.el6.x86_64'


Now you will see the file called hello.ko in directory where you compiled the module.

[root@localhost hello]# ls -l
total 308
-rw-rw-r--. 1 sujin sujin   301 Aug 17 17:08 hello.c
-rw-r--r--. 1 root  root  95415 Aug 17 17:18 hello.ko
-rw-r--r--. 1 root  root  95415 Aug 17 17:18 hello.ko.unsigned
-rw-r--r--. 1 root  root    818 Aug 17 17:18 hello.mod.c
-rw-r--r--. 1 root  root  54816 Aug 17 17:18 hello.mod.o
-rw-r--r--. 1 root  root  42210 Aug 17 17:18 hello.o
-rw-rw-r--. 1 sujin sujin   156 Aug 17 16:57 Makefile
-rw-r--r--. 1 root  root     52 Aug 17 17:19 modules.order
-rw-r--r--. 1 root  root      0 Aug 17 17:18 Module.symvers

Insert the kernel module using insmod. insmod command will call init_module() function from program. You should be sudo user to insert module to the kernel

[root@localhost hello]# insmod hello.ko

You can see the installed kernel module using lsmod command
[root@localhost hello]# lsmod | head
Module                  Size  Used by
hello                    892  0
ipt_addrtype            2153  2
xt_conntrack            2776  1
ipt_MASQUERADE          2466  1
iptable_nat             6158  1
nf_nat                 22759  2 ipt_MASQUERADE,iptable_nat
bridge                 83689  0
dm_thin_pool           46566  1
dm_bio_prison           6346  1 dm_thin_pool


It is not possible to see the output of printk in terminal, because module loaded in kernel space not in user space. Instead kernel put printk output in logfile, you can see those message from log file using dmesg command.

[root@localhost hello]# dmesg | tail
SELinux: initialized (dev cgroup, type cgroup), uses genfs_contexts
SELinux: initialized (dev cgroup, type cgroup), uses genfs_contexts
Bridge firewalling registered
8021q: adding VLAN 0 to HW filter on device docker0
SELinux: initialized (dev fuse, type fuse), uses genfs_contexts
eth0: no IPv6 routers present
docker0: no IPv6 routers present
hello: module license 'unspecified' taints kernel.
Disabling lock debugging due to kernel taint
Hello World

By using rmmod command you can remove the module from kernel. It will call the cleanup_module() function in the module program

[root@localhost hello]# rmmod hello

Now you can see the cleanup message from logfile using dmesg command.

[root@localhost hello]# dmesg | tail
SELinux: initialized (dev cgroup, type cgroup), uses genfs_contexts
Bridge firewalling registered
8021q: adding VLAN 0 to HW filter on device docker0
SELinux: initialized (dev fuse, type fuse), uses genfs_contexts
eth0: no IPv6 routers present
docker0: no IPv6 routers present
hello: module license 'unspecified' taints kernel.
Disabling lock debugging due to kernel taint
Hello World
Bye Bye


That's it !!! Well done. Finally we done hello world kernel module programming.

I am not the owner of this article. I grabbed details from other articles. Full credits goes to author of The Linux Kernel Module Programming Guide.


Enjoy Linux


   
   





No comments:

Post a Comment