• Creating a “hello world” kernel module in linux

    by  • October 4, 2009 • kernel module, linux, networking • 6 Comments

    This is part one of my series on creating a Netfilter module in order to implement a routing protocol in Linux. I’ve broken down the challenge into three steps.

    1. Write a simple kernel module (this article)
    2. Add Netfilter hooks to kernel module
    3. Access packet headers within Netfilter hook
    4. Abstract routing daemon to a user space module (for easier debugging)

    This post concerns writing a simple “hello world” kernel module, to illustrate the build process and the installation and uninstallation of the module. My build environment is Ubuntu 8.04, so for those users of other distros, YMMV. I followed a tutorial over at http://www.cyberciti.biz/tips/build-linux-kernel-module-against-installed-kernel-source-tree.html to get  me started.

    You’ll need to install build-essential and the linux headers for your distro. I am running Ubuntu 8.04, which runs kernel version 2.6.24-23, so I needed to run:
    sudo apt-get install build-essential linux-headers-2.6.24-23
    This will also provide access to make, which we will need in order to compile the module. With this method, you don’t need the Linux source, just the header files which is great.

    There is a much easier way of setting up the Ubuntu build environment using module assistant, to build kernel modules. Follow the guide here and then come back here.

    So, now we have the build environment set up, we are going to code up the simple module, implementing the necessary methods, init_module(void) and cleanup_module(void). All the module does is to log these method calls, as a result of installing and removing the module, to /var/log/messages

    hello.c
    
    //'Hello World' kernel module, logs call to init_module
    // and cleanup_module to /var/log/messages
    
    // In Ubuntu 8.04 we use make and appropriate Makefile to compile kernel module
    
    #define __KERNEL__
    #define MODULE
    
    #include <linux/module.h>
    #include <linux/kernel.h>
    
    int init_module(void)
    {
     printk(KERN_INFO "init_module() called\n");
     return 0;
    }
    
    void cleanup_module(void)
    {
     printk(KERN_INFO "cleanup_module() called\n");
    }

    In order to compile the module, we create an associated Makefile, like the following:

    Makefile
    
    obj-m := hello.o
    KDIR := /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)
    default:
     $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

    Then, within our working folder, type make, which will process the Makefile and create a module file, hello.ko

    To install the module,type:

    sudo insmod hello.ko

    To remove the module, type:

    sudo rmmod hello.ko

    To verify the module has output to the log file, type:

    tail /var/log/messages

    You should see the relevant log messages init_module() called and cleanup_module() called in this file.

    The next post will show how we can create a simple Netfilter installable module based on this hello world kernel module which simply drops any packets, and logs this fact.

    About

    .NET developer at thetrainline.com, previously web developer at MRM Meteorite. Awarded a PhD in misbehaviour detection in wireless ad-hoc networks.A keen C# ASP.net developer bridging the gap with APIs and JavaScript frameworks, one web app at a time.

    http://www.paulkiddie.com

    6 Responses to Creating a “hello world” kernel module in linux

    1. Pingback: Paul Kiddie’s Blog : Creating a simple ‘hello world’ Netfilter module

    2. Pingback: Paul Kiddie’s Blog : Creating a Netfilter kernel module which filters UDP packets

    3. Pingback: Paul Kiddie’s Blog : Installing Xen on Ubuntu 8.04 and creating Ubuntu 8.04 domU’s (guests)

    4. Pingback: Paul Kiddie’s Blog : Update on setting up Ubuntu in order to build kernel modules

    5. December 29, 2012 at 1:31 pm

      Hello Paul;

      tks for the tutorial. A very good start up.

      Just a tip: If somebody copy/paste the script (as I did), it will not run: The command line after “default:” must start with a “tab” (when you paste it from Chrome it becomes some spaces).

      Best Regards
      Taka

    6. Vinay Dwivedi
      January 25, 2013 at 7:25 am

      Thanks a lot Paul. Your post helped me in starting driver programming. I am really enjoying it now.

    Leave a Reply

    Your email address will not be published. Required fields are marked *