Home » Linux Kernel » Writing first Linux kernel Module

Writing first Linux kernel Module

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 
$ cd module_workspace 
 $ vim hello.c 
#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

[Note: Make sure you have added TAB before “make” in above makefile ]

Now, compile this kernel module for Ubuntu based host,

$ make
make -C /lib/modules/5.4.0-90-generic/build M=/home/devlab/devlab/kernel_module modules
make[1]: Entering directory '/usr/src/linux-headers-5.4.0-90-generic'
  CC [M]  /home/devlab/devlab/kernel_module/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: modpost: missing MODULE_LICENSE() in /home/devlab/devlab/kernel_module/hello.o
see include/linux/module.h for more information
  CC [M]  /home/devlab/devlab/kernel_module/hello.mod.o
  LD [M]  /home/devlab/devlab/kernel_module/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-90-generic'
$ ls
hello.c  hello.ko  hello.mod  hello.mod.c  hello.mod.o  hello.o  Makefile  modules.order  Module.symvers
$ file hello.ko
hello.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=b233f3be8ee0cf063554188edfb6f62eca370c0e, not stripped
$ tree
.
├── hello.c
├── hello.ko
├── hello.mod
├── hello.mod.c
├── hello.mod.o
├── hello.o
├── Makefile
├── modules.order
└── Module.symvers

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

Load and Unload Kernel Modules in L...
Load and Unload Kernel Modules in Linux - Ansible module modprobe

1 thought on “Writing first Linux kernel Module”

Leave a Comment