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.
Post a comment
|