edit · history · print

Copied from the Kernel Module Programming Guide (KMPG)

Writing, Building and Running a Module

/* hello-1.c - The simplest kernel module.
 */
#include <linux/module.h>	/* Needed by all modules */
#include <linux/kernel.h>	/* Needed for KERN_INFO */
int init_module(void) 
{
	printk(KERN_INFO "Hello world 1.\n");
	return 0; /* 0 means success in the kernel */
}
void cleanup_module(void)
{
	printk(KERN_INFO "Goodbye world 1.\n");
}

Note that printk takes a level before its format - the level is actually a string that gets pasted together with the format, so there is no comma between the two. Printk supports most printf format codes, although you don't want to use floating point.

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

If you've built modules for the 2.4 kernel (or earlier) the 2.6 build system is very simple in comparison - you just point 'make' at the kernel source directory, pass M=$(PWD), and it just works. If your kernel source tree is somewhere else, then you can specify it in the makefile or on the command line:

  make KERNEL_DIR=/some/path/linux-1.67.2 all

Here are the results of compiling and installing this module:

[pjd@george tmp]$ make all
make -C /lib/modules/2.6.17-1.2174_FC5/build M=/tmp modules
make[1]: Entering directory `/usr/src/kernels/2.6.17-1.2174_FC5-i586'
  CC [M]  /tmp/hello-1.o
  Building modules, stage 2.
  MODPOST
  CC      /tmp/hello-1.mod.o
  LD [M]  /tmp/hello-1.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.17-1.2174_FC5-i586'
[pjd@george tmp]$ sudo insmod hello-1.ko
[pjd@george tmp]$ sudo rmmod hello-1
[pjd@george tmp]$ dmesg | tail 
 ...
hello_1: module license 'unspecified' taints kernel.
Hello world 1.
Goodbye world 1.

To remove the 'taint' message you need to specify a GPL license, by adding the following line at the bottom of the .c file:

  MODULE_LICENSE("GPL");

Module versions

Some operating systems (e.g. Windows 2000, XP) export a kernel-level interface (e.g. for drivers) which remains stable for years, across many systems; that's why the driver disk that came with an old network card may still work. The kernel-level interface in Linux not only changes frequently between versions, but can even change depending on configuration options. (the biggest change here is probably due to enabling or disabling SMP)

To prevent errors due to a mismatch in interfaces (e.g. different numbers of function arguments) Linux provides the module versioning feature. [TODO - write more] You should never have trouble with symbol versions if you are compiling against the same kernel tree that you are running kernels from.

Advanced topics

  • multi-file modules [TODO]
  • module parameters [TODO]
  • module busy / unload [TODO]

Of course, we haven't talked about the code inside the module yet...

edit · history · print
Page last modified on September 14, 2006, at 08:55 AM EST