Intention

Recently, i thought to learn about linux device drivers and started reading LDD, so I will be summarizing my learnings here. So, Simple step towards linux device driver is writing a simple module. I am using ubuntu machine and will be doing experiments on that.


1. Writing a Simple Loadable Module

Basically, a module:

  • Registers an entry function (called at load time)
  • Registers an exit function (called at unload time)

Here is the minimal, correct “Hello World” module:

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

MODULE_LICENSE("GPL"); // General Public License
MODULE_AUTHOR("jdecodes"); // author name
MODULE_DESCRIPTION("Minimal jdecodes kernel module"); // module description

// initialization function
// __init macro comes from linux/init.h
static int __init jdecodes_init(void)
{
    pr_info("jdecodes_init: loaded into kernel\n");
    for (int i = 0; i < 5; i++) {
        pr_info("jdecodes_init: Hello, jdecodes! Count: %d\n", i);
    }
    return 0;
}

static void __exit jdecodes_exit(void)
{
    pr_info("jdecodes_exit: removed from kernel\n");
}

// register the module
module_init(jdecodes_init);
// unregister the module
module_exit(jdecodes_exit);

Key points

  • module_init() tells the kernel where execution begins
  • module_exit() tells the kernel how to clean up
  • pr_info() logs messages to the kernel log (dmesg)
  • __init and __exit help the kernel manage memory efficiently

2. Writing the Makefile

Kernel modules must be built using the kernel build system. Create a file “MakeFile“make -C $KDIR M=$PWD [Targets]

obj-m := hello.o

# given compiling against host machine 
# so, need to compile aganist correct version
# which we can get via "uname -r"
# to read that do " $ (shell uname -r)"

KDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean

What this does

obj-y → built-in (static module along with kernel)
obj-m → module
obj-n → disabled

  • obj-m declares a loadable module
  • The kernel’s own Makefile handles compilation and linking
  • The result is a .ko (kernel object) file

all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
1 question which can arise is how make can build hello.ko, as we did not define any modules. well, that is already pass to obj-m as hello.ko, so kernel build system knows the exact path where it is build and module it needs to build. I will write a detailed article on Make system.


3. Compiling the Module

Run:

make

This produces several files, the most important being:

  • hello.ko — the actual kernel module
  • hello.o — compiled object
  • Module.symvers — symbol versioning metadata

Only hello.ko is loaded into the kernel.


4. Loading the Module into the Kernel

Loading a module requires root privileges:

sudo insmod hello.ko

The command itself produces no output.
To confirm execution, check the kernel log:

dmesg | tail

You should see:

[24942.100132] hello: loading out-of-tree module taints kernel. 
[24942.100132 hello: module verification failed: signature and/or
[24942.100132] jdecodes_init: loaded into kernel
[24942.100136] jdecodes_init: Hello, jdecodes! Count: 0
[24942.100138] jdecodes_init: Hello, jdecodes! Count: 1
[24942.100139] jdecodes_init: Hello, jdecodes! Count: 2
[24942.100140] jdecodes_init: Hello, jdecodes! Count: 3
[24942.100141] jdecodes_init: Hello, jdecodes! Count: 4

You can also verify that the module is present:

lsmod | grep hello

5. Removing the Module

To unload the module:

sudo rmmod hello
dmesg | tail
[25400.539604] jdecodes_exit: removed from kernel

If removal fails, it usually means the module did not clean up correctly—something the kernel takes very seriously. atleast, writing a simple module, looks simple, we will see how complex the drivers become once we move further..

Read next article : https://jdecodes.wordpress.com/2026/01/13/linux-device-drivers-101-002-writing-pseudo-char-driver/

Leave a comment

It’s Jdecoder

I am trying to decode the concepts into simple words and documenting items i know or currently learning.

Let’s connect

Design a site like this with WordPress.com
Get started