Kernel Module Dev Environment

I’ve been poking at kernel development recently; partly for fun, partly for career growth, partly because I want to understand the layers I’ve leaned on for years.

This post continues that thread: small, incremental steps, written as reminders to mys…


This content originally appeared on DEV Community and was authored by Adam Weber

I’ve been poking at kernel development recently; partly for fun, partly for career growth, partly because I want to understand the layers I’ve leaned on for years.

This post continues that thread: small, incremental steps, written as reminders to myself and hopefully helpful to anyone taking a similar path.

This time, I wanted to get a kernel module development environment working end-to-end. Nothing glamorous. No drivers. No deep dives into subsystems. Just:

Build the kernel
Boot QEMU with it
Build a module
Insert it
Watch it say hello
Remove it

As usual, half the battle is just wiring together all the moving pieces correctly. So this post documents what I did, what worked, and what I want to remember later.

Step 1

Set up a dedicated folder for modules

First lesson: keep module work isolated so you don’t end up polluting the kernel tree.

mkdir -p ~/kernel/hello
cd ~/kernel/hello

Good fences make good neighbors.

Step 2

Write the simplest possible module

Kernel modules are surprisingly small once you strip away the noise. Here’s the entire thing:

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

MODULE_LICENSE("GPL");
MODULE_AUTHOR("AWs.");
MODULE_DESCRIPTION("Hello world kernel module");
MODULE_VERSION("0.1");

static int __init hello_init(void)
{
    pr_info("Hello: module loaded!\n");
    return 0;
}

static void __exit hello_exit(void)
{
    pr_info("Hello: module unloaded!\n");
}

module_init(hello_init);
module_exit(hello_exit);

It loads, prints a message, and unloads. Found in console output as well as dmesg.

One thing I wanted to remind myself here:
Userland logging is not kernel logging.

Use pr_info() instead of printf(). Muscle memory is strong, but so is printk. Note to self, explore the rest of the pr_* macros.

Step 3

Use the kernel’s build system.

Create a Makefile:

obj-m += hello.o

KDIR := /path/to/your/kernel/source
PWD := $(shell pwd)

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

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

Setting KDIR to my source path.

Step 4

Build it

make

Once I got everything lined up correctly I got:

hello.ko

Step 5

Get the module into QEMU (virtio-fs)

The nicest way to test that I could find was adding the following to my qemu alias. There is almost certainly a better way to do this, such that I won't have to modify it for other modules.

-fsdev local,id=mods,path=~/kernel-dev/hello,security_model=none \
-device virtio-9p-pci,fsdev=mods,mount_tag=mods

Then inside the VM:

mkdir -p /mnt/mods
mount -t 9p -o trans=virtio mods /mnt/mods

Mounting the hosts modules folder

Step 6

Insert the module

Inside the VM:

insmod /mnt/mods/hello.ko

Confirm with dmesg

dmesg | tail

in which I found

Hello: module loaded!

Along with a warning about polluting the kernel.

finally remove it.

rmmod hello

and again:

dmesg | tail

I observed

Hello: module unloaded!

What this means for me:

I built my own kernel
I booted it
I built a module against it
I loaded that module into the kernel
I then unloaded it from the kernel

This is my pipeline for future kernel work. If you have experience let me know any tips or changes you think I should make.

What I’m doing next:

Probably /proc/hello or a sysfs attribute. Maybe standing up a minimal character driver.

The working dev environment was the real milestone.

If you’re doing your own kernel experiments, I’d love to hear what you’re building.


This content originally appeared on DEV Community and was authored by Adam Weber


Print Share Comment Cite Upload Translate Updates
APA

Adam Weber | Sciencx (2025-11-28T19:05:13+00:00) Kernel Module Dev Environment. Retrieved from https://www.scien.cx/2025/11/28/kernel-module-dev-environment/

MLA
" » Kernel Module Dev Environment." Adam Weber | Sciencx - Friday November 28, 2025, https://www.scien.cx/2025/11/28/kernel-module-dev-environment/
HARVARD
Adam Weber | Sciencx Friday November 28, 2025 » Kernel Module Dev Environment., viewed ,<https://www.scien.cx/2025/11/28/kernel-module-dev-environment/>
VANCOUVER
Adam Weber | Sciencx - » Kernel Module Dev Environment. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/11/28/kernel-module-dev-environment/
CHICAGO
" » Kernel Module Dev Environment." Adam Weber | Sciencx - Accessed . https://www.scien.cx/2025/11/28/kernel-module-dev-environment/
IEEE
" » Kernel Module Dev Environment." Adam Weber | Sciencx [Online]. Available: https://www.scien.cx/2025/11/28/kernel-module-dev-environment/. [Accessed: ]
rf:citation
» Kernel Module Dev Environment | Adam Weber | Sciencx | https://www.scien.cx/2025/11/28/kernel-module-dev-environment/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.