Writing Device Drivers

What Is the Kernel?

The Solaris kernel is a program that manages system resources. It insulates applications from the system hardware and provides them with essential system services such as input/output (I/O) management, virtual memory, and scheduling. The kernel consists of object modules that are dynamically loaded into memory when needed.

One way to look at the Solaris kernel is to divide it into two parts: the first part, referred to as the kernel, manages file systems, scheduling, and virtual memory. The second part, referred to as the I/O subsystem, manages the physical components.

The kernel provides a set of interfaces for applications to use that are accessible through system calls. System calls are documented in the Solaris 9 Reference Manual Collection (see Intro(2)). Some system calls are used to invoke device drivers to perform I/O. Device drivers are loadable kernel modules that manage data transfers while insulating the rest of the kernel from the device hardware. To be compatible with the operating environment, device drivers need to be able to accommodate such features as multithreading, virtual memory addressing, and both 32–bit and 64–bit operation.

The following figure illustrates the kernel, with the kernel modules handling system calls from application programs and the I/O modules communicating with hardware.

Figure 1–1 The Solaris Kernel

Diagram shows calls from user-level applications to specific kernel-level modules, and calls between drivers and other modules to devices.

The kernel provides access to device drivers through:

Multithreaded Execution Environment

The Solaris kernel is multithreaded. On a multiprocessor machine, multiple kernel threads can be running kernel code, and can do so concurrently. Kernel threads can also be preempted by other kernel threads at any time.

The multithreading of the kernel imposes some additional restrictions on device drivers. For more information on multithreading considerations, see Chapter 3, Multithreading. Device drivers must be coded to run as needed at the request of many different threads. For each thread, it must handle contention problems from overlapping I/O requests.

Virtual Memory

A complete overview of the Solaris virtual memory system is beyond the scope of this book, but two virtual memory terms of special importance are used when discussing device drivers: virtual address and address space.

Devices as Special Files

Devices are treated as files. They are represented in the file system by special files. In the Solaris operating environment these files reside in the /devices directory hierarchy.

Special files can be of type block or character. The type indicates which kind of device driver operates the device. Drivers can be implemented to operate on both types. For example, disk drivers export a character interface for use by the fsck(1) and mkfs(1) utilities, and a block interface for use by the file system.

Associated with each special file is a device number (dev_t). This consists of a major number and a minor number. The major number identifies the device driver associated with the special file. The minor number is created and used by the device driver to further identify the special file. Usually, the minor number is an encoding that identifies the device instance the driver should access and the type of access to perform. The minor number, for example, could identify a tape device used for backup and also specify whether the tape needs to be rewound when the backup operation is complete.

DDI/DKI Interfaces

In System V Release 4 (SVR4), the interface between device drivers and the rest of the UNIX kernel was standardized as the DDI/DKI. The Solaris 9 DDI/DKI is documented in Section 9 of the Solaris 9 Reference Manual Collection. This section documents driver entry points, driver-callable functions, and kernel data structures used by device drivers.

The Solaris 9 DDI/DKI, like its SVR4 counterpart, is intended to standardize and document all interfaces between device drivers and the rest of the kernel. In addition, the Solaris 9 DDI/DKI allows source compatibility for drivers on any machine running the Solaris 9 operating environment, regardless of the processor architecture (such as SPARC or IA). It is also intended to provide binary compatibility for drivers running on any Solaris 9–based processor, regardless of the specific platform architecture. Drivers using only kernel facilities that are part of the Solaris 9 DDI/DKI are known as Solaris 9 DDI/DKI-compliant device drivers.

The Solaris 9 DDI/DKI allows platform-independent device drivers to be written for Solaris 9 based machines. These shrink-wrapped (binary compatible) drivers enable third-party hardware and software to be more easily integrated into Solaris 9-based machines. The Solaris 9 DDI/DKI is designed to be architecture independent and enable the same driver to work across a diverse set of machine architectures.

Platform independence is accomplished by the design of DDI in Solaris 9 DDI/DKI. The following main areas are addressed: