The Windows 2000 Device Driver Book: A Guide for Programmers (2nd Edition)

< BACK  NEXT >
[oR]

Kernel-Mode I/O Components

The purpose of this section is to describe the goals and architecture of the Windows 2000 I/O subsystem. Since different kinds of drivers perform wildly different kinds of service, the I/O Manager's categorization of drivers is also discussed.

Design Goals for the I/O Subsystem

The I/O subsystem of Windows 2000 added to the overall design goals of the operating system by including

  • Portability, platform to platform.

  • Configurability in terms of both hardware and software. For Windows 2000 drivers, this would include full support for Plug and Play buses and devices.

  • Preemptable and interruptable. I/O code should never block and should always be written thread-safe.

  • Multiprocessor-safe. The same I/O code should run on both uniprocessor and multiprocessor configurations.

  • Object-based. The services provided by I/O code should be offered in encapsulated data structures with well-defined allowable operations.

  • Packet-driven. Requests made of the I/O subsystem should be submitted and tracked using a distinct "work order" format, known as an I/O Request Packet (IRP).

  • Asynchronous I/O support. Requests made of the I/O subsystem should be allowed to complete in parallel with the requestor's execution. When the request ultimately completes, a mechanism must exist to notify the caller of completion.

Besides these published goals, there is also strong emphasis placed on code reusability. This translates to heavy structuring of I/O code (including drivers) into logical layers. For example, bus-driving code should be layered separately from specific device code to allow for reuse of the bus code across multiple devices. In many cases, different vendors supply code for different layers. Only through careful modularization can this goal be achieved.

Kinds of Drivers in Windows 2000

There once was a time when a device driver author could understand the intricacies of the new hardware, learn the OS device driver interface, scope the work, and "just write the code." For better or worse, the days of monolithic device driver code have passed. Today, an author must understand the architectures of both complex hardware buses and heavily layered I/O subsystems just to scope the work statement. Deciding what kind of driver to write for Windows 2000 is itself an interesting challenge. Deciding whether to implement or to reuse a layer is yet another challenge. The purpose of this section is to describe where different kinds of drivers fit within the hardware world and the OS.

At the highest level, Windows 2000 supports two kinds of drivers, user-mode and kernel-mode. User-mode drivers, as the name implies, is system-level code running in user mode. Examples include a simulated, or virtualized, driver for imaginary hardware or perhaps a new environmental subsystem. Since Windows 2000 user mode does not allow direct access to hardware, a virtualized driver necessarily relies upon real driver code running in kernel mode. This book does not describe user-mode drivers. The purpose of this book is to describe real drivers, which in Windows 2000 are known as kernel-mode drivers.

Kernel-mode drivers consist of system-level code running in kernel mode. Since kernel mode allows direct hardware access, such drivers are used to control hardware directly. Of course, nothing prevents a kernel-mode driver from virtualizing real hardware the choice between user and kernel mode is largely an implementer's choice. Again, however, the purpose of this book is to present the strategies for implementing true kernel-mode drivers for real hardware.

Moving down a level, kernel-mode drivers can be further decomposed into two general categories, legacy and Windows Driver Model (WDM). Legacy drivers were fully described in the first edition of this book. The techniques needed to discover hardware and interface with the I/O subsystem are well documented. Thankfully, most of the knowledge gained by understanding legacy Windows NT drivers is transportable to the Windows 2000 (and Windows 98) WDM world.

WDM drivers are Plug and Play compliant. They support power management, autoconfiguration, and hot plugability. A correctly written WDM driver is usable on both Windows 2000 and Windows 98, though at present, Microsoft does not guarantee binary compatibility. At most, a rebuild of the driver source is necessary using the Windows 98 DDK (Device Driver Kit).

Moving down yet another level, legacy and WDM drivers can be further decomposed into three categories, high-level, intermediate, and low-level. As the names imply, a high-level driver depends on intermediate and low-level drivers to complete its work. An intermediate driver depends on a low-level driver to complete its work.

High-level drivers include file system drivers (FSDs). These drivers present a nonphysical abstraction to requestors that, in turn, is translated into specific device requests. The need to write a high-level driver is apparent when the underlying hardware services are already provided by lower levels only a new abstraction is required for presentation to requestors.

Microsoft supplies an Installable File System (IFS) kit, sold separately from MSDN or any other product. The IFS kit requires the DDK (and other products) for successful file system development. There are numerous restrictions on the types of file systems that can be developed using this kit. For pricing and ordering information, you can visit the HWDEV virtual site of Microsoft's Internet site. This book does not address file system development.

Intermediate drivers include such drivers as disk mirrors, class drivers, mini drivers, and filter drivers. These drivers insert themselves between the higher-level abstractions and the lower-level physical support. For example, a disk mirror receiving the request from the high-level FSD to write to a file translates such a request into two requests of two different low-level disk drivers. Neither the higher nor lower levels need to be aware that mirroring is, in fact, occurring.

Class drivers are an elegant attempt at code reuse within the driver model. Since many drivers of a particular type have much in common, the common code can be placed in a generic class driver separate from the physical, device-specific code. For example, all IDE disk drivers share considerable similarity. It is possible to write the common code once, placing it in a generic class driver that loads as an intermediate driver. Vendor and device specific IDE drivers would then be written as mini drivers that interact with the generic class driver.

Filter drivers are intermediate drivers that intercept requests to an existing driver. They are given the opportunity to modify requests before presentation to the existing driver.

Finally, within the WDM world, intermediate drivers can also consist of Functional Drivers. These drivers can be either class or mini drivers, but they always act as an interface between an abstract I/O request and the low-level physical driver code. Within the DDK documentation, the term Functional Driver is sometimes interchanged with Class or Mini Driver. The context determines the meaning.

Low-level drivers include controllers for the hardware buses. For example, the SCSI Host Bus Adapter is one such low-level driver. Such drivers interact with Windows 2000 HAL layer and/or the hardware directly. In the WDM world, low-level drivers include the notion of a Physical Driver. These Physical Drivers interact with one or more Functional Drivers.

Figure 1.3 shows the driver classifications in Windows 2000.

Figure 1.3. Driver classifications in Windows 2000.

< BACK  NEXT >

Категории