What Is the Kernel?
The Solaris kernel is a program that manages system resources. The kernel 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.
The Solaris kernel can be divided logically 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 section 2 of the 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 system,
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. The kernel modules handle system calls from
application programs. The I/O modules communicate with hardware.
Figure 2-1 Solaris Kernel
The kernel provides access to device drivers through the following features:
Device-to-driver mapping. The kernel maintains the device tree. Each node in the tree represents a virtual or a physical device. The kernel binds each node to a driver by matching the device node name with the set of drivers installed in the system. The device is made accessible to applications only if there is a driver binding.
DDI/DKI interfaces. DDI/DKI (Device Driver Interface/Driver-Kernel Interface) interfaces standardize interactions between the driver and the kernel, the device hardware, and the boot/configuration software. These interfaces keep the driver independent from the kernel and improve the driver's portability across successive releases of the operating system on a particular machine.
LDI. The LDI (Layered Driver Interface) is an extension of the DDI/DKI. The LDI enables a kernel module to access other devices in the system. The LDI also enables you to determine which devices are currently being used by the kernel. See Chapter 14, Layered Driver Interface (LDI).
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, a
driver 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.
Virtual address. A virtual address is an address that is mapped by the memory management unit (MMU) to a physical hardware address. All addresses directly accessible by the driver are kernel virtual addresses. Kernel virtual addresses refer to the kernel address space.
Address space. An address space is a set of virtual address segments. Each segment is a contiguous range of virtual addresses. Each user process has an address space called the user address space. The kernel has its own address space, called the kernel address space.
Devices as Special Files
Devices are represented in the file system by special files. In the Solaris OS, 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). A device number
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 is used to identify which device instance the
driver should access and which type of access should be performed. For example,
the minor number can identify a tape device used for backup and can
specify that 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 DDI/DKI
is documented in section 9 of the Reference Manual Collection. Section 9E documents driver entry points, section
9F documents driver-callable functions, and section 9S documents kernel data structures used by
device drivers. See Intro(9E), Intro(9F), and Intro(9S).
The DDI/DKI is intended to standardize and document all interfaces between device drivers
and the rest of the kernel. In addition, the DDI/DKI enables source and
binary compatibility for drivers on any machine that runs the Solaris OS, regardless
of the processor architecture, whether SPARC or x86. Drivers that use only kernel
facilities that are part of the DDI/DKI are known as DDI/DKI-compliant device drivers.
The DDI/DKI enables you to write platform-independent device drivers for any machine that
runs the Solaris OS. These binary-compatible drivers enable you to more easily integrate
third-party hardware and software into any machine that runs the Solaris OS. The
DDI/DKI is architecture independent, which enables the same driver to work across a
diverse set of machine architectures.
Platform independence is accomplished by the design of DDI in the following areas:
Dynamic loading and unloading of modules
Power management
Interrupt handling
Accessing the device space from the kernel or a user process, that is, register mapping and memory mapping
Accessing kernel or user process space from the device using DMA services
Managing device properties