The kernel-mode parts of Windows 2000 (including a device driver) consist of massive amounts of code. But just what causes this code to execute? All code executes within a hardware and software context. A context, as used here, describes the state of the system while a CPU instruction executes. It includes the state of all CPU registers (including the stack), the processor mode (user or kernel), and significantly, the state of the hardware page tables. This last item describes what memory can be seen by executing code, and where within the address space that memory is located. Clearly, code must make assumptions about the context in which it executes. Windows 2000 defines three execution contexts for kernel-mode execution. In other words, kernel-mode driver code executes in one of three contexts. Trap or Exception ContextChapter 1 described how user-mode code can request an OS service by trapping into kernel mode. When a kernel-mode routine executes, it may be because a user-mode application or service caused a hardware or software exception, or trap, to occur. In this case, the context of the kernel-mode code is largely that of the user code that caused the exception. The memory seen by kernel-mode code includes the same view as seen by the requesting user-mode thread. When a user-mode thread makes a direct request of the I/O Manager, the I/O Manager executes within the context of the requester. In turn, the I/O Manager may call a dispatch routine within a device driver. Dispatch routines of a driver therefore execute within this exception context. Interrupt ContextWhen the hardware (or software) generates an acknowledged interrupt, whatever code is executing within the system is stopped dead in its tracks. The executing context is saved and control is promptly handed over to a service routine appropriate for the kind of interrupt that occurred. Clearly, the context of the executing code at the time of the interrupt is irrelevant and arbitrary. Kernel-mode code servicing the interrupt cannot make any assumptions about the state of the page tables. User-mode buffers must be considered unavailable in this context. Code running in interrupt context (which includes the bulk of driver routines) can make no assumptions about the current process or thread. Kernel-Mode Thread ContextThe final possibility is that a piece of code runs in the context of a separate kernel thread. Some drivers spawn separate threads to deal with devices that require polling or to deal with specialized timeout conditions. These kernel-mode threads are not significantly different from user-mode threads described in Win32 programming books. They execute when scheduled by the kernel's scheduler, in accordance with the assigned thread priority. Like the interrupt context, kernel-mode thread context can make no assumption about the current process or thread. The state of the page tables is largely arbitrary as seen by the thread. Chapter 14 discusses the use of kernel-mode threads.
|