Compiling and Loading
The rest of this chapter is devoted to writing a complete, though typeless, module. That is, the module will not belong to any of the classes listed in Section 1.3, in Chapter 1. The sample driver shown in this chapter is called skull, short for “Simple Kernel Utility for Loading Localities.” You can reuse the skull source to load your own local code to the kernel, after removing the sample functionality it offers.[4]
Before we deal with the roles of init_module and
cleanup_module, however, we’ll write a Makefile
that
builds object code that the kernel can load.
First, we need to define the __KERNEL__
symbol in the
preprocessor before we include any headers. This symbol is used to
select which parts of the headers are actually used. Applications
end up including kernel headers because libc includes
them,[5] but
the applications don’t need all the kernel prototypes. Therefore,
__KERNEL__
is used to mask the extra ones out via #ifdef
.
Exporting kernel symbols and macros to user-space programs would
greatly contribute to program namespace pollution. If you are compiling
for an SMP (Symmetric Multi-Processor) machine, you also need
to define __SMP__
before including the kernel headers. This
requirement may seem unfriendly, but is going to disappear as
soon as the developers find the right way to be SMP-transparent.
Another important symbol is MODULE
, which must be defined
before including <linux/module.h>
. This symbol is always defined, except when compiling ...
Get Linux Device Drivers now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.