1    Introduction to Kernel Modules

This chapter presents an overview of kernel modules by discussing the following topics:

1.1    What Is a Kernel Module?

A kernel module is a binary image containing code and data structures that runs in the UNIX kernel. It has the following characteristics:

The kernel contains many modules, some of which are device drivers. In this book, a kernel module is defined more broadly than a device driver because it can be used to perform a variety of functions, including:

1.1.1    Purpose of a Kernel Module

The kernel consists of a set of kernel modules that interact with each other, each performing a specific function. Some kernel modules perform software functions exclusively, while others (such as device drivers) control the operation of system hardware components.

A purpose for writing a kernel module is to provide a middle layer of code, or common code, thus increasing the efficiency of your system by combining like tasks in a single area and eliminating redundant code.

For example, assume you need to write a SCSI driver for disk and tape peripheral devices. You could write two monolithic drivers-one for each hardware device-but this would mean replicating a majority of the code, while only a small amount would differ. By writing a kernel module containing common code, you eliminate this redundancy (see ). One class driver might handle SCSI tapes and another handle SCSI disks. Both call the kernel module, which sends the I/O request to a variety of port drivers. The port drivers send requests to the SCSI controller. As you add more disk or tape drives to your system, the kernel module would seamlessly manage the expansion, while controller-specific code would be confined to the new port drivers. Similarly, you can add a different SCSI device (for example, a scanner) by writing a new class driver. The kernel module would maintain a consistent interface to the other kernel modules and make adding the new driver easier.

1.1.2    Kernel Module Environment

shows a kernel module in relationship to other modules in the kernel. As a binary image, a kernel module can be loaded statically as part of /vmunix or dynamically loaded into memory. In this example, the kernel module is part of a driver subsystem.

Figure 1-1:  Kernel Module Environment

The following list describes the main components in .

Application

A user-mode program that, in the context of this book, makes various requests to the kernel modules. If a kernel module is part of a device driver, these requests typically perform I/O operations to hardware components. Another term for application is utility.

Bus

A hardware component that connects multiple buses and controllers to the system.

Class/Port Driver

The class/port driver comprises two drivers. The class driver supports user interfaces while the port driver supports the hardware and handles interrupts. The driver model is always made of more than one module and it can have multiple class drivers, multiple port drivers, and some common code in a middle layer. The structure of this driver eliminates code duplication.

Controller

A hardware component that performs a specific function, such as communicate on the network or control the graphics monitor.

Device

A hardware component that is connected to a controller.

Device Driver

A kernel module that supports one or more hardware components. There are two driver models: the monolithic driver model and the class/port driver model.

Interrupt

A signal from a hardware component that eventually causes the interrupt handler in the appropriate driver to be called.

Kernel Module

A .mod file residing in the kernel that executes common code. In , the kernel module is part of a device driver.

Kernel Space

Activities that happen within the UNIX kernel. Modules may be statically loaded as part of /vmunix or dynamically loaded as needed. The module framework, which in can be thought of as the background area of kernel space, loads, unloads, makes management requests, and keeps track of the modules in kernel space.

Library

User-mode code that is called by applications. Libraries contain routines that perform common functions used by many applications.

Monolithic Driver

Kernel module code that is all-inclusive; supporting everything from user requests to processing interrupts from hardware.

Pseudodevice driver

A pseudodevice driver, such as the pty terminal driver, structured like other drivers but not operating on a bus and not controlling hardware. A pseudodevice driver does not register itself in the hardware topology (system configuration tree). Instead, it relies on the device driver method of the cfgmgr framework to create the associated device special files.

Switch Table

A data structure in the kernel where the block and character I/O interface entry points are stored.

System Routines

Routines in the kernel that can be called from user mode (applications and libraries).

User Space

User application level or command-line interface to the operating system.

1.1.3    Designing a Kernel Module

The following are guidelines for you to consider when designing your kernel module:

1.2    Writing a Kernel Module -- Key Tasks

This book is organized so that key tasks for writing a kernel module are logically grouped:

1.2.1    Required Tasks

All kernel module writers need to understand module initialization, creating the module attribute table, using callbacks, and working in kernel mode. The following sections describe these tasks.

Initializing a Kernel Module

Kernel module initialization occurs in both static and dynamic mode. Kernel module writers must understand the concept of a single binary image, the build-load-initialize sequence, and how to use the configure routine to perform initialization tasks to add a kernel module (make it known to the kernel) or to remove it. Chapter 2 describes these concepts and the required tasks for coding your kernel module to initialize properly. It also describes how to unload dynamically loaded modules.

Creating the Attribute Table

All kernel modules must contain an attribute table. Chapter 3 describes a variety of tasks you can perform on the module attribute table to retrieve data from the table and set data in the table.

Using Callbacks

Kernel modules contain one or more callback routines that perform different aspects of initialization along the boot timeline. Coding callback routines in a kernel module is a key task for creating a kernel module that may function as a single binary image. Chapter 4 describes the rules for using callbacks in a kernel module. It discusses callbacks in relation to dispatch points along the boot timeline, and how the kernel calls the kernel module's callback routine.

Working in Kernel Mode

You can perform many tasks in kernel mode. Chapter 5 describes how to:

1.2.2    Additional Tasks

If your kernel module executes in a symmetric multiprocessing (SMP) environment or uses kernel threads, you must perform additional tasks, as described in the following sections.

Working in an SMP Enviroment

Selecting a locking methodology and coding the correct type of lock in your kernel module are key tasks for writing kernel modules that execute in an SMP environment. Chapter 6 through Chapter 8 describe how to:

Working with Kernel Threads

Chapter 9 describes the key concepts and tasks for developing kernel modules that use kernel threads. These include:

1.2.3    Building and Testing a Kernel Module

After you have written your kernel module, the next task is to build the executable module (a .mod file) and test it. Chapter 10 walks you through steps to build and test your kernel module.