2.1. Hello,
World (part 1): The Simplest Module
When the first caveman programmer chiseled the first program on
the walls of the first cave computer, it was a program to paint the
string `Hello, world' in Antelope pictures. Roman programming
textbooks began with the `Salut, Mundi' program. I don't know what
happens to people who break with this tradition, but I think it's
safer not to find out. We'll start with a series of hello world
programs that demonstrate the different aspects of the basics of
writing a kernel module.
Here's the simplest module possible. Don't compile it yet; we'll
cover module compilation in the next section.
Example 2-1. hello-1.c
/*
* 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");
/*
* A non 0 return means init_module failed; module can't be loaded.
*/
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}
|
Kernel modules must have at least two functions: a "start"
(initialization) function called init_module() which is called when the module is
insmoded into the kernel, and an "end" (cleanup) function called
cleanup_module() which is called just
before it is rmmoded. Actually, things have changed starting with
kernel 2.3.13. You can now use whatever name you like for the start
and end functions of a module, and you'll learn how to do this in
Section 2.3. In fact, the new method is
the preferred method. However, many people still use init_module() and cleanup_module() for their start and end
functions.
Typically, init_module() either
registers a handler for something with the kernel, or it replaces
one of the kernel functions with its own code (usually code to do
something and then call the original function). The cleanup_module() function is supposed to undo
whatever init_module() did, so the module
can be unloaded safely.
Lastly, every kernel module needs to include linux/module.h. We needed to include linux/kernel.h only for the macro expansion for the
printk() log level, KERN_ALERT, which you'll learn about in Section 2.1.1.
2.1.1. Introducing printk()
Despite what you might think, printk()
was not meant to communicate information to the user, even though
we used it for exactly this purpose in hello-1! It happens to be a logging mechanism
for the kernel, and is used to log information or give warnings.
Therefore, each printk() statement comes
with a priority, which is the <1>
and KERN_ALERT you see. There are 8
priorities and the kernel has macros for them, so you don't have to
use cryptic numbers, and you can view them (and their meanings) in
linux/kernel.h. If you don't specify a
priority level, the default priority, DEFAULT_MESSAGE_LOGLEVEL, will be used.
Take time to read through the priority macros. The header file
also describes what each priority means. In practise, don't use
number, like <4>. Always use the
macro, like KERN_WARNING.
If the priority is less than int
console_loglevel, the message is printed on your current
terminal. If both syslogd and klogd are running, then the message will also
get appended to /var/log/messages,
whether it got printed to the console or not. We use a high
priority, like KERN_ALERT, to make sure
the printk() messages get printed to your
console rather than just logged to your logfile. When you write
real modules, you'll want to use priorities that are meaningful for
the situation at hand.