Posted by: Catalin | September 29, 2008

First Linux loadable kernel module

All long voyages have a first step.

Some first loadable kernel module may seen trivial but it’s worth seeing.

Furthermore it’s considered obvious that you’ve already:

  • Explored  the Linux 2.6 kernel source repository , unpacked the latest kernel source into /usr/src and linked its directory to /usr/src/linux
  • Copied the /boot/config-`uname -r` into /usr/src/linux and the did a make oldconfig there

If you are using GNU Debian/Linux or maybe Ubuntu:

  • Installed the kernel-package and maybe some other software packages.
  • Changed directory into /usr/src/linux, compiled the kernel and packed it into a deb file with make-kpkg –initrd <whatever> command.
  • Installed the compiled kernel with dpkg -i <its deb file> and already rebooted the machine.  (VMware virtual machine?)

Now you have the newest Linux kernel running into your testing environment and you’re ready to attack your first lkm.

Following source code is quite trivial and could be considered a skeleton. Code is self explanatory.

first.c

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

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Copyright Whoever (C) Whenever 2008");

static int first_init(void) {

        int ret;

        /*      Do whatever initializings here. If some fails
         * you should uninitialize everyting initialized till
         * failure in reverse order.
         *
         * You could achieve this with goto statements.
         */

        printk(KERN_INFO "first module: loaded\n");
        return 0;

first_module_err:
        printk(KERN_INFO "first module: not loaded\n");
        return ret;
}
static void first_exit(void) {
        printk(KERN_INFO "first module unloaded\n");
}

module_init(first_init);
module_exit(first_exit);

OK, now you have a valid source code of your first lkm and you wish to compile and load it! That’s made simple if you like to automate you task using shell. Keep in mind that GNU make is your friend.

Following code is a valid makefile that could be used:

Makefile

obj-m = first.o

KERNELDIR=/usr/src/linux
CWD=$(shell pwd)

.PHONY:clean

default: clean
        make -C $(KERNELDIR) I=$(CWD) M=$(CWD);   \
        insmod first.ko

clean:
        @INSERTED=`lsmod | grep first`;            \
         if [ ! -z "$$INSERTED" ]; then            \
            rmmod first;                           \
         fi;                                       \
         find . -name '.[a-z A-Z]*' -o -name '*.o' \
             -o -name '*.ko' -o -name '*.mod.c'    \
             -o -name 'Module.*' -o -name 'modul*' \
             | xargs rm -rf

Having those two files: first.c and Makefile into a testing directory you can compile and load the module performing one single command: make. Makefile has an auxiliary target you can follow: clean, that will erase every temporary file and directories resulting from compilation process and will unload the module.

If you want to see module’s messages you can perform a dmesg | tail on your shell.

Enjoy!



Responses

  1. [...] Regarding a Makefile you can find a good example here. [...]


Leave a response

Your response:

Categories