nixCraft Poll

Topics

How to: Compile Linux kernel modules

Posted by Vivek Gite [Last updated: October 26, 2007]

This is one the essential and important task. Many time we upgrade our kernel and some precompiled drivers won't work with Linux. Especially if you have weird hardware; then vendor may send you driver code aka C files to compile. Or even you can write your own Linux kernel driver. Compiling kernel driver is easy. Kernel 2.6.xx makes it even much more easier. Following steps are required to compile driver as module:

1) You need running kernel source code; if you don't have a source code download it from kernel.org. Untar kernel source code (tar ball) in /usr/src using tar command:
$ tar -zxvf kernel* -C /usr/src

To be frank kernel headers are more than sufficient to compile kernel modules / drivers. See how to install kernel headers under Debian / Ubuntu Linux or RHEL / CentOS / Fedora Linux.

2) Next go to your kernel module source code directory and simply create the Makefile file as follows (assuming your kernel module name is foo):
$ vi Makefile

3) Add following text to it:

obj-m = foo.o
KVERSION = $(shell uname -r)
all:
        make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
        make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean

4) Compile module using make command (module build can be done by any user) :
$ make
It will finally creates the foo.ko module in current directory. You can see all actual compile command stored in .foo* files in same directory.

5) Once module compiled successfully, load it using insmod or modprobe command. You need to be root user or privileged user to run insmod:
# insmod foo.ko

Example: hello.c module

1) hello.c C source code. Copy following code and save to hello.c
$ mkdir demo; cd demo
$ vi hello.c

2)Add following c source code to it:

#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for KERN_INFO */
#include <linux/init.h>         /* Needed for the macros */

static int __init hello_start(void)
{
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
return 0;
}

static void __exit hello_end(void)
{
printk(KERN_INFO "Goodbye Mr.\n");
}

module_init(hello_start);
module_exit(hello_end);

This is an example modified from original source for demonstration purpose.

3) Save the file. Create new Makefile as follows:
$ vi Makefile
Append following make commands:

obj-m = hello.o
KVERSION = $(shell uname -r)
all:
        make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
        make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean

4) Save and close the file.

5) Compile hello.c module:
$ make

6) Become a root user (use su or sudo) and load the module:
$ su -
# insmod hello.ko

Note you can see message on screen if you are logged in as root under run level 3.

7) Verify that module loaded:
# lsmod | less

8) See message in /var/log/message file:
# tail -f /var/log/message

9) Unload the module:
# rmmod hello

10) Load module when Linux system comes up. File /etc/modules use to load kernel boot time. This file should contain the names of kernel modules that are to be loaded at boot time, one per line. First copy your module to /lib/modules/$(uname -r)/kernel/drivers. Following are suggested steps:

(a) Create directory for hello module:
# mkdir -p /lib/modules/$(uname -r)/kernel/drivers/hello
(b) Copy module:
# cp hello.ko /lib/modules/$(uname -r)/kernel/drivers/hello/
(c) Edit /etc/modules file under Debian Linux:
# vi /etc/modules
(d) Add following line to it:
hello
(e) Reboot to see changes. Use lsmod or dmesg command to verify module loaded or not.
# cat /proc/modules
OR
# lsmod | less

See also:

Want to stay up to date with the latest Linux tips, news and announcements? Subscribe to our free e-mail newsletter or RSS feed to get all updates. You can Email this page to a friend.

You may also be interested in other helpful articles:

Discussion on This Article:

  1. Anonymous Says:

    Aha … intresting gone try this.

  2. swift Says:

    hi when i compile this by running make file this type of erro occcur …what to do

    make -f make
    make -C /lib/modules/2.6.18-1.2798.fc6/build M=/home/mclamna modules
    make[1]: Entering directory `/usr/src/kernels/2.6.18-1.2798.fc6-i686′
    scripts/Makefile.build:17: /home/mclamna/Makefile: No such file or directory
    make[2]: *** No rule to make target `/home/mclamna/Makefile’. Stop.
    make[1]: *** [_module_/home/mclamna] Error 2
    make[1]: Leaving directory `/usr/src/kernels/2.6.18-1.2798.fc6-i686′
    make: *** [all] Error 2

  3. shan Says:

    dis s wat i encountered wen using

    CHK include/linux/version.h
    CHK include/linux/utsrelease.h
    HOSTCC scripts/basic/fixdep
    In file included from /usr/include/bits/posix1_lim.h:153,
    from /usr/include/limits.h:145,
    from /usr/lib/gcc/i486-linux-gnu/4.1.2/include/limits.h:122,
    from /usr/lib/gcc/i486-linux-gnu/4.1.2/include/syslimits.h:7,
    from /usr/lib/gcc/i486-linux-gnu/4.1.2/include/limits.h:11,
    from scripts/basic/fixdep.c:113:
    /usr/include/bits/local_lim.h:36:26: error: linux/limits.h: No such file or directory
    In file included from /usr/include/sys/socket.h:35,
    from /usr/include/netinet/in.h:24,
    from /usr/include/arpa/inet.h:23,
    from scripts/basic/fixdep.c:115:
    /usr/include/bits/socket.h:310:24: error: asm/socket.h: No such file or directory
    scripts/basic/fixdep.c: In function ‘use_config’:
    scripts/basic/fixdep.c:204: error: ‘PATH_MAX’ undeclared (first use in this function)
    scripts/basic/fixdep.c:204: error: (Each undeclared identifier is reported only once
    scripts/basic/fixdep.c:204: error: for each function it appears in.)
    scripts/basic/fixdep.c:204: warning: unused variable ‘s’
    scripts/basic/fixdep.c: In function ‘parse_dep_file’:
    scripts/basic/fixdep.c:300: error: ‘PATH_MAX’ undeclared (first use in this function)
    scripts/basic/fixdep.c:300: warning: unused variable ‘s’
    make[1]: *** [scripts/basic/fixdep] Error 1
    make: *** [scripts_basic] Error 2

  4. Nitin Says:

    Hi swift, I guess u have not created Makefile in ur present directory, plz make sure that makefile name is correct and its case sensitive, it should be ‘Makefile’.

  5. Nitin Says:

    Hi, This was very much helpful but now I’m stuck because i didn’t understand how this particular makefile is working, so i’m not able to write it for multiple files. Please could anyone explain how this makefile works with a example for multiple files.
    Thanks,
    Nitin.

  6. john Says:

    how to cross compile lkm for arm?

Leave a Reply

We encourage your comments, and suggestions. But please stay on topic, be polite, and avoid spam. Thank you very much for stopping by our site!

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word

Tags: , , , , , , ,

Copyright © 2004-2008 nixCraft. All rights reserved - TOS/Disclaimer - Privacy policy - Sitemap - Powered by Open source software.