By Alessandro Rubini, Jonathan Corbet
Cover | Table of Contents | Colophon
http://www.tux.org/lkml. Please read the rest of
the FAQ while you are at it; there is a great deal of useful
information there. Linux kernel developers are busy people, and they
are much more inclined to help people who have clearly done their
homework first.
#define MODULE
#include <linux/module.h>
int init_module(void) { printk("<1>Hello, world\n"); return 0; }
void cleanup_module(void) { printk("<1>Goodbye cruel world\n"); }
<1> is the priority of the message. We've
specified a high priority (low cardinal number) in this module because
a message with the default priority might not show on the console,
depending on the kernel version you are running, the version of the
klogd daemon, and your configuration. You
can ignore this issue for now; we'll explain it in Section 4.1.1 in Chapter 4.
__KERNEL__ symbol in the
preprocessor before we include any headers. As mentioned earlier, much
of the kernel-specific content in the kernel headers is unavailable
without this symbol.
MODULE, which must be
defined before including <linux/module.h>
(except for drivers that are linked directly into the kernel). This
book does not cover directly linked modules; thus, the
MODULE symbol is always defined in our examples.
__SMP__ before including the kernel
headers. In version 2.2, the "multiprocessor or uniprocessor" choice
was promoted to a proper configuration item, so using these lines as
the very first lines of your modules will do the task:
#include <linux/config.h> #ifdef CONFIG_SMP # define __SMP__ #endif
inline in the header
files. gcc doesn't expand inline functions
unless optimization is enabled, but it can accept both the
-g and -O
options, allowing you to debug code that uses inline
functions. Because the kernel makes
extensive use of inline functions, it is important that they be
expanded properly.
register_, so another
possible way to find them is to grep for register_
in /proc/ksyms.
GFP_KERNEL or
GFP_USER will do. The GFP
acronym stands for "get free page." (Memory allocation is covered in
detail in Chapter 7.)
KERNEL_VERSION macro was
introduced in kernel 2.1.90. The sysdep.h header
file contains a replacement for kernels that need it.
0 for kernels earlier than 2.4.
void (thus forcing the use of
check_region beforehand). The new implementation,
more correctly, has functions that return a pointer value so that an
error condition can be signaled (thus making
__KERNEL__
MODULE
__SMP__
int init_module(void);
void cleanup_module(void);
#include <linux/init.h>
module_init(init_function);
module_exit(cleanup_function);
#include <linux/module.h>
MOD_INC_USE_COUNT;
crw-rw-rw- 1 root root 1, 3 Feb 23 1999 null crw------- 1 root root 10, 1 Feb 23 1999 psaux crw------- 1 rubini tty 4, 1 Aug 16 22:22 tty1 crw-rw-rw- 1 root dialout 4, 64 Jun 30 11:19 ttyS0 crw-rw-rw- 1 root dialout 4, 65 Aug 16 00:00 ttyS1 crw------- 1 root sys 7, 1 Feb 23 1999 vcs1 crw------- 1 root sys 7, 129 Feb 23 1999 vcsa1 crw-rw-rw- 1 root root 1, 5 Feb 23 1999 zero
file structure, and the
kernel uses the file_operations structure to access
the driver's functions. The structure, defined in
<linux/fs.h>, is an array of function
pointers. Each file is associated with its own set of functions (by
including a field called f_op that points to a
file_operations structure). The operations are
mostly in charge of implementing the system calls and are thus named
open, read, and so on. We
can consider the file to be an "object" and the functions operating
on it to be its "methods," using object-oriented programming
terminology to denote actions declared by an object to act on itself.
This is the first sign of object-oriented programming we see in the
Linux kernel, and we'll see more in later chapters.
file_operations structure or a
pointer to one is called fops (or some variation
thereof); we've already seen one such pointer as an argument to the
register_chrdev call. Each field in the structure
must point to the function in the driver that implements a specific
operation, or be left NULL for unsupported
operations. The exact behavior of the kernel when a
NULL pointer is specified is different for each
function, as the list later in this section shows.
file_operations structure has been slowly
getting bigger as new functionality is added to the kernel. The
addition of new operations can, of course, create portability problems
for device drivers. Instantiations of the structure in each driver
used to be declared using standard C syntax, and new operations were
normally added to the end of the structure; a simple recompilation of
the drivers would place a NULL value for that
operation, thus selecting the default behavior, usually what you
wanted.
struct file, defined in
<linux/fs.h>, is the second most important
data structure used in device drivers. Note that a
file has nothing to do with the
FILEs of user-space programs. A
FILE is defined in the C library and never appears
in kernel code. A struct file, on the other hand,
is a kernel structure that never appears in user programs.
file structure represents an open
file. (It is not specific to device drivers; every open file
in the system has an associated struct file in
kernel space.) It is created by the kernel on
open and is passed to any function that operates
on the file, until the last close. After all
instances of the file are closed, the kernel releases the data
structure. An open file is different from a disk file, represented by
struct inode.
struct file is
usually called either file or
filp ("file pointer"). We'll consistently call
the pointer filp to prevent ambiguities with the
structure itself. Thus, file refers to the
structure and filp to a pointer to the structure.
struct file are shown
here. As in the previous section, the list can be skipped on a first
reading. In the next section though, when we face some real C code,
we'll discuss some of the fields, so they are here for you to refer
to.
mode_t f_mode;
FMODE_READ and
FMODE_WRITE. You might want to check this field for
read/write permission in your ioctl function, but
you don't need to check permissions for read and
write because the kernel checks before invoking
your method. An attempt to write without permission, for example, is
rejected without the driver even knowing about it.
f_op
pointer, if necessary
filp->private_data
inode->i_rdev.
Scull_Dev
structure. Each such structure can refer, by default, to at most four
million bytes, through an array of intermediate pointers. The
released source uses an array of 1000 pointers to areas of 4000
bytes. We call each memory area a