Compile a Linux Kernel Module

Makefile

If you have a file, say, traverse.o, then your Makefile should be like the following

obj-m += traverse.o

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

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

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

What $(shell uname -r) basically does is that it is replaced by the output of the terminal command uname -r, which lists the directory of your Linux heders.

Insert the Kernel Module

$ sudo insmod traverse.ko

To see the output

$ dmesg

Remove the Kernel Module

$ sudo rmmod traverse.ko

Cautions

for_each_process

If your code is like the following

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

int init_module(void)
{
    struct task_struct *task;
    for_each_process(task)
{
    printk("%s [%d]\n",task->comm , task->pid);
}

return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Cleaning Up.\n");
}

You may get the error

error: implict declaration of function 'for_each_process': did you mean 'for each node'? [-Werror=implicit-funciton-declaration]
    for_each_process(task)
    for_each_node

Solution

You should add the following library explicitly

#include <linux/sched/signal.h>

include

instead of

#include < linux/kernel.h >

one should write

#include <linux/kernel.h>

This is subtle, but in GCC it just won’t work. As in Reference 1, the style is buggy. And will cause the fatal error: linux/kernel.h : No such file or directory. These extra spaces that caused the error are really hard to find out.

References

  1. Bad style in #include: https://linuxgazette.net/133/saha.html
  2. for_each_process: https://github.com/Douane/douane-dkms/issues/24