2.2. Compiling
Kernel Modules
Kernel modules need to be compiled a bit differently from
regular userspace apps. Former kernel versions required us to care
much about these settings, which are usually stored in Makefiles.
Although hierarchically organized, many redundant settings
accumulated in sublevel Makefiles and made them large and rather
difficult to maintain. Fortunately, there is a new way of doing
these things, called kbuild, and the build process for external
loadable modules is now fully integrated into the standard kernel
build mechanism. To learn more on how to compile modules which are
not part of the official kernel (such as all the examples you'll
find in this guide), see file linux/Documentation/kbuild/modules.txt.
So, let's look at a simple Makefile for compiling a module named
hello-1.c:
Example 2-2. Makefile for a basic kernel module
obj-m += hello-1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
|
From a technical point of view just the first line is really
necessary, the "all" and "clean" targets were added for pure
convenience.
Now you can compile the module by issuing the command make . You should obtain an output which resembles
the following:
hostname:~/lkmpg-examples/02-HelloWorld# make
make -C /lib/modules/2.6.11/build M=/root/lkmpg-examples/02-HelloWorld modules
make[1]: Entering directory `/usr/src/linux-2.6.11'
CC [M] /root/lkmpg-examples/02-HelloWorld/hello-1.o
Building modules, stage 2.
MODPOST
CC /root/lkmpg-examples/02-HelloWorld/hello-1.mod.o
LD [M] /root/lkmpg-examples/02-HelloWorld/hello-1.ko
make[1]: Leaving directory `/usr/src/linux-2.6.11'
hostname:~/lkmpg-examples/02-HelloWorld#
|
Note that kernel 2.6 introduces a new file naming convention:
kernel modules now have a .ko extension
(in place of the old .o extension) which
easily distinguishes them from conventional object files. The
reason for this is that they contain an additional .modinfo section
that where additional information about the module is kept. We'll
soon see what this information is good for.
Use modinfo hello-*.ko to see what kind
of information it is.
hostname:~/lkmpg-examples/02-HelloWorld# modinfo hello-1.ko
filename: hello-1.ko
vermagic: 2.6.11 preempt PENTIUMII 4KSTACKS gcc-3.3
depends:
|
Nothing spectacular, so far. That changes once we're using
modinfo on one of our the later examples, hello-5.ko .
hostname:~/lkmpg-examples/02-HelloWorld# modinfo hello-5.ko
filename: hello-5.ko
license: GPL
author: Peter Jay Salzman
vermagic: 2.6.11 preempt PENTIUMII 4KSTACKS gcc-3.3
depends:
parm: myintArray:An array of integers (array of int)
parm: mystring:A character string (charp)
parm: mylong:A long integer (long)
parm: myint:An integer (int)
parm: myshort:A short integer (short)
hostname:~/lkmpg-examples/02-HelloWorld#
|
Lot's of useful information to see here. An author string for
bugreports, license information, even a short description of the
parameters it accepts.
Additional details about Makefiles for kernel modules are
available in linux/Documentation/kbuild/makefiles.txt. Be sure
to read this and the related files before starting to hack
Makefiles. It'll probably save you lots of work.
Now it is time to insert your freshly-compiled module it into
the kernel with insmod ./hello-1.ko (ignore
anything you see about tainted kernels; we'll cover that
shortly).
All modules loaded into the kernel are listed in /proc/modules. Go ahead and cat that file to see
that your module is really a part of the kernel. Congratulations,
you are now the author of Linux kernel code! When the novelty wears
off, remove your module from the kernel by using rmmod hello-1. Take a look at /var/log/messages just to see that it got logged to
your system logfile.
Here's another exercise for the reader. See that comment above
the return statement in init_module()?
Change the return value to something negative, recompile and load
the module again. What happens?