Wednesday, 4 April 2018

Writing first Linux kernel Module and understanding Kernel module compilation, loading and unloading

We will try to understand the simple kernel driver which initially we will compile for ubuntu host and later for a embedded hardware.
 $ mkdir module_workspace 
 $ vim hello.c 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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 __init hello_init(void)
{
printk(KERN_INFO “Hello, world\n”);
return 0;
}
 
static void __exit hello_exit(void)
{
printk(KERN_INFO “Goodbye, world\n”);
}
 
module_init(hello_init);
module_exit(hello_exit);
Create a Makefile,
 $ vim 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, compile this kernel module for ubuntu x86 based host,
$ make
make -C /lib/modules/3.19.0-30-generic/build M=/home/devbee/devlab/module_workspace modules
make[1]: Entering directory '/usr/src/linux-headers-3.19.0-30-generic'
CC [M] /home/devbee/devlab/module_wokspace/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/devbee/devlab/module_workspace/hello.mod.o
LD [M] /home/devbee/devlab/module_workspace/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-3.19.0-30-generic'
 $ ls
hello.c hello.mod.c hello.o modules.order
hello.ko hello.mod.o Makefile Module.symvers
 $ file hello.ko
hello.ko: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), BuildID[sha1]=2a1da63ae5631484cc4db328425ad533b8b7b5a0, not stripped
$ tree
.
├── hello.c
├── hello.ko
├── hello.mod.c
├── hello.mod.o
├── hello.o
├── Makefile
├── modules.order
└── Module.symvers

0 directories, 8 files
The “tree” command shows the output files generated during compilation process. Now, we will try to insert that module to kernel as,
$ sudo insmod ./hello.ko
Notice, the error if any, now you can check if the module is successfully inserted to the system,
$ dmesg
[ 2260.748252] hello: module license 'unspecified' taints kernel.
[ 2260.748261] Disabling lock debugging due to kernel taint
[ 2260.748315] hello: module verification failed: signature and/or required key missing - tainting kernel
[ 2260.748790] Hello, world
$ lsmod | grep hello
hello 16384 0
Notice that the module has been inserted into the system with some license warning, which we will try to understand ahead, lsmod shows the list of modules running.
Now, lets try to remove this module from kernel as below,
$ sudo rmmod hello
$ dmesg
[ 3026.031566] Goodbye, world
above dmesg command shows, rmmod command called “module_exit” from our driver and displayed the message.
Here, in above code we had got th e following warning,
$ dmesg
[ 2260.748252] hello: module license 'unspecified' taints kernel.
[ 2260.748261] Disabling lock debugging due to kernel taint
[ 2260.748315] hello: module verification failed: signature and/or required key missing - tainting kernel
This was due to missing LICENSE, so we added the following lines at the end of kernel module hello.c
MODULE_AUTHOR(“DEVBEE”);
MODULE_DESCRIPTION(“Hello World Example”);
MODULE_LICENSE(“GPL”);
Which will remove this warning.
$ make 
$ sudo insmod ./hello.ko 
$ dmesg
[ 4051.863842] Hello, world
In our next post, we will try to understand “Passing command line Arguments / Parameters to Linux kernel module

No comments: