Brief items
The current development kernel is 2.5.59; no development kernels
have been released since January 16.
Linus is back from his travels, and has merged some 300 patches (as of this
writing) into his BitKeeper tree. They include some JFS updates, a number
of kbuild changes (including the merge of the new modversions code), a new
aic7xxx driver, an ALSA update, various network driver fixes, a number of
USB updates, a big rework of the SCSI command block allocation code, and
more.
The current stable kernel is 2.4.20; there have been no 2.4.21
prepatches from Marcelo in the last week.
Alan Cox has released a couple of patches, the most recent being 2.4.21-pre4-ac2. Quite a bit of IDE work has
been going on, and this patch should be handled carefully. (Indeed, there
have been some reports of IDE-related deadlocks with the -ac2 patch).
Comments (2 posted)
Kernel development news
One bit of unfinished 2.5 business is "initramfs," the boot-time root
filesystem which is tacked onto the kernel binary image. The plan is to
move much of the initialization-time code out of the kernel and into
initramfs; the result should be a smaller kernel and a safer, more flexible boot
process.
The code to support initramfs has been in the kernel for some time. The
big missing piece has been on the user space side. Before anything useful
can be run in user mode as part of the boot process, there must be a whole
environment to build it in. Attaching the C library to the kernel image
is not an option that would appeal to many, so a special-purpose C library
is needed. That library is "klibc," which has been under development by
Greg Kroah-Hartman and others for some time. klibc provides a minimal set
of standard functions, written with an eye toward portability and small
size.
Greg recently posted an update on klibc.
The library seems to be essentially complete, at least until somebody tries
to do something requiring functions which have not been provided. The
sticking point, at the moment, seems to be a bug in the initramfs unpacking
code. Greg is interested in input from anybody who would like to help
debug that problem. Once that's been ironed out, it is mostly just a
matter of figuring out which boot-time operations should be taken out of
the kernel and moved into a user-space implementation. If that is going to
happen in 2.5, it would be nice if it happened soon; making major changes
to the boot process brings with it a real risk of destabilizing the kernel
for a while.
Comments (3 posted)
Your editor is currently in the middle of porting the example source from
Linux Device Drivers,
Second Edition to the 2.5 kernel. This work is, of course, just the
beginning of the rather larger job of updating the whole book. This
article is the first in what will, hopefully, be a series describing what
is required to make this code work again. The series will thus, with luck,
be useful as a guide to how to port drivers to the new kernel API.
The obvious place to start in this sort of exercise, of course, is the
classic "hello world" program, which, in this context, is implemented as a
kernel module. The 2.4 version of this module looked like:
#define MODULE
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
printk(KERN_INFO "Hello, world\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye cruel world\n");
}
One would not expect that something this simple and useless would require
much in the way of changes, but, in fact, this module will not quite work
in a 2.5 kernel. So what do we have to do to fix it up?
The first change is relatively insignificant; the first line:
#define MODULE
is no longer necessary, since the kernel build system (which you really
should use now, see the next article) defines it for you.
The biggest problem with this module, however, is that you have to
explicitly declare your initialization and cleanup functions with
module_init and module_exit, which are found in
<linux/init.h>. You really should have done that for 2.4 as
well, but you could get away without it as long as you used the names
init_module and cleanup_module. You can still sort of
get away with it (though you may have to ignore some compiler warnings),
but the new module code broke this way of doing things once, and could do
so again. It's really time to bite the bullet and do things right.
With these changes, "hello world" now looks like:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
This module will now work - the "Hello, world" message shows up in the
system log file. What also shows up there, however, is a message reading
"hello: module license 'unspecified' taints kernel." "Tainting" of the
kernel is (usually) a way of indicating that a proprietary module has been
inserted, which is not really the case here. What's missing is
a declaration of the license used by the module:
MODULE_LICENSE("Dual BSD/GPL");
MODULE_LICENSE is not exactly new; it was added to the 2.4.10
kernel. Some older code may still lack
MODULE_LICENSE calls,
however. They are worth adding; in addition to avoiding the "taints
kernel" message, a license declaration gives your module access to GPL-only
kernel symbols. Assuming, of course, that the module is GPL-licensed.
With these changes, "hello world" works as desired. At least, once you
have succeeded in building it properly; that is the subject of the next
article.
Comments (26 posted)
The 2.5 development series saw extensive changes to the kernel build mechanism and
the complete replacement of the module loading code. One result of these
changes is that compiling loadable modules has gotten a bit more
complicated. In the 2.4 days, a makefile for an external module could be
put together in just about any old way; typically a form like the following
was used:
KERNELDIR = /usr/src/linux
CFLAGS = -D__KERNEL__ -DMODULE -I$(KERNELDIR)/include -O
all: module.o
Real-world makefiles, of course, tended to be a bit more complicated, but
the job of creating a loadable module was handled in a single, simple
compilation step. All you really needed was a handy set of kernel headers
to compile against.
With the 2.6 kernel, you still need those headers. You also, however, need
a configured kernel source tree and a set of makefile rules describing how
modules are built. There's a few reasons for this:
- The new module loader needs to have some extra symbols defined at
compilation time. Among other things, it needs to have the
KBUILD_BASENAME and KBUILD_MODNAME symbols defined.
- All loadable modules now need to go through a linking step - even those
which are built from a single source file. The link brings in
init/vermagic.o from the kernel source tree; this object
creates a special section in the loadable module describing the
environment in which it was built. It includes the compiler version
used, whether the kernel was built for SMP, whether kernel preemption
is enabled, the architecture which was compiled for, and, of course,
the kernel version. A difference in any of these parameters can
render a module incompatible with a given running kernel; rather than
fail in mysterious ways, the new module loader opts to detect these
compatibilities and refuse to load the module.
As of this writing (2.5.59), the "vermagic" scheme is fallible in that
it assumes a match between the kernel's vermagic.o file and
the way the module is being built. That will normally be the case,
but people who change compiler versions or perform some sort of
compilation trickery could get burned.
- The new symbol versioning scheme ("modversions") requires a separate
post-compile processing step and yet another linkable object to hold
the symbol checksums.
One could certainly, with some effort, write a new, standalone makefile
which would handle the above issues. But that solution, along with being a
pain, is also brittle; as soon as the module build process changes again,
the makefile will break. Eventually that process will stabilize, but, for
a while, further changes are almost guaranteed.
So, now that you are convinced that you want to use the kernel build system
for external modules, how is that to be done? The first step is to learn
how kernel makefiles work in general; makefiles.txt from a recent kernel's
Documentation/kbuild directory is recommended reading. The
makefile magic needed for a simple kernel module is minimal, however. In
fact, for a single-file module, a single-line makefile will suffice:
obj-m := module.o
(where
module is replaced with the actual name of the resulting
module, of course). The kernel build system, on seeing that declaration,
will compile
module.o from
module.c, link it with
vermagic.o, and leave the result in
module.ko, which can
then be loaded into the kernel.
A multi-file module is almost as easy:
obj-m := module.o
module-objs := file1.o file2.o
In this case,
file1.c and
file2.c will be compiled, then
linked into
module.ko.
Of course, all this assumes that you can get the kernel build system to
read and deal with your makefile. The magic command to make that happen is
something like the following:
make -C /path/to/source SUBDIRS=$PWD modules
Where
/path/to/source is the path to the source directory for the
(configured and built)
target kernel. This command causes make to head over to the kernel source
to find the top-level makefile; it then moves back to the original
directory to build the module of interest.
Of course, typing that command could get tiresome after a while. A trick
posted by Gerd Knorr can make things a little easier, though. By looking
for a symbol defined by the kernel build process, a makefile can determine
whether it has been read directly, or by way of the kernel build system.
So the following will build a module against the source for the currently
running kernel:
ifneq ($(KERNELRELEASE),)
obj-m := module.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif
Now a simple "make" will suffice. The makefile will be read twice; the
first time it will simply invoke the kernel build system, while the actual
work will get done in the second pass. A makefile written in this way is
simple, and it should be robust with regard to kernel build changes.
Comments (57 posted)
Here's one feature which didn't get in before the freeze: morse code kernel
panics, recently
updated to 2.5 by Tomas
Szepe. With this patch, a 2.5 kernel which goes into a panic state
will blink out the panic message in morse code using the keyboard LEDs.
Possible future enhancements include audio output using the PC speaker or a
sound card. One developer has
mentioned the
possibility of having a nearby machine with a microphone to detect and
decode the encoded panic message.
One might well be tempted to object that the number of people clamoring for
this feature has been relatively small. But there is actually a serious
side to this patch. It is well known that production Linux systems never
panic, but if, someday, a box were to be struck by a cosmic ray and go
down, its owner might like to know about it. Preferably before the "where
has your site been this last week?" mail starts to show up. The morse code
patch could, with a bit of work, be the beginning of a more general panic
notification feature. It could be useful, even if you hope you never
actually make use of it.
Comments (10 posted)
Patches and updates
Kernel trees
Core kernel code
Development tools
Device drivers
Documentation
Filesystems and block I/O
Janitorial
Memory management
- Rik van Riel: rmap 15c.
(January 30, 2003)
- Rik van Riel: rmap 15d.
(January 31, 2003)
Networking
Architecture-specific
Security-related
Benchmarks and bugs
Miscellaneous
Page editor: Jonathan Corbet
Next page: Distributions>>