LWN.net Logo

 


 
Summary page
Return to the Kernel page
 
Recent Features

LWN.net Weekly Edition for March 18, 2004

LWN.net Weekly Edition for March 11, 2004

The annotated SCO stock price chart

A grumpy editor's calendar search

LWN.net Weekly Edition for March 4, 2004

Printable page
 

 

Driver porting: hello world

This article is part of the LWN Porting Drivers to 2.6 series.
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

  Driver porting: hello world
(Posted Feb 14, 2003 5:19 UTC (Fri) by rusty) (Post reply)

Hi Jon,

I appeciate the series in modernizing modules, but just FYI, I don't think the old-style init_module/cleanup_module stuff will break any time soon: there are still a large number of drivers which use it, and there's not much point making such changes.

However, this "new" scheme (introduced by Linus in 2.3 IIRC) has the advantage that your module will work correctly when built into the kernel: you want that initialization routine called, even then.

So I hope that clarifies,
Rusty.

Copyright (©) 2003, Eklektix, Inc.
Linux (®) is a registered trademark of Linus Torvalds
Powered by Rackspace Managed Hosting.