Читаем Windows® Internals, Sixth Edition, Part 1 полностью

One set of kernel objects, called control objects, establishes semantics for controlling various operating system functions. This set includes the APC object, the deferred procedure call (DPC) object, and several objects the I/O manager uses, such as the interrupt object.

Another set of kernel objects, known as dispatcher objects, incorporates synchronization capabilities that alter or affect thread scheduling. The dispatcher objects include the kernel thread, mutex (called mutant internally), event, kernel event pair, semaphore, timer, and waitable timer. The executive uses kernel functions to create instances of kernel objects, to manipulate them, and to construct the more complex objects it provides to user mode. Objects are explained in more detail in Chapter 3, and processes and threads are described in Chapter 5.

Kernel Processor Control Region and Control Block (KPCR and KPRCB)

The kernel uses a data structure called the processor control region, or KPCR, to store processor-specific data. The KPCR contains basic information such as the processor’s interrupt dispatch table (IDT), task-state segment (TSS), and global descriptor table (GDT). It also includes the interrupt controller state, which it shares with other modules, such as the ACPI driver and the HAL. To provide easy access to the KPCR, the kernel stores a pointer to it in the fs register on 32-bit Windows and in the gs register on an x64 Windows system. On IA64 systems, the KPCR is always located at 0xe0000000ffff0000.

The KPCR also contains an embedded data structure called the kernel processor control block (KPRCB). Unlike the KPCR, which is documented for third-party drivers and other internal Windows kernel components, the KPRCB is a private structure used only by the kernel code in Ntoskrnl.exe. It contains scheduling information such as the current, next, and idle threads scheduled for execution on the processor; the dispatcher database for the processor (which includes the ready queues for each priority level); the DPC queue; CPU vendor and identifier information (model, stepping, speed, feature bits); CPU and NUMA topology (node information, cores per package, logical processors per core, and so on); cache sizes; time accounting information (such as the DPC and interrupt time); and more. The KPRCB also contains all the statistics for the processor, such as I/O statistics, cache manager statistics (see Chapter 11, “Cache Manager,” in Part 2 for a description of these), DPC statistics, and memory manager statistics. (See Chapter 10 in Part 2 for more information.) Finally, the KPRCB is sometimes used to store cache-aligned, per-processor structures to optimize memory access, especially on NUMA systems. For example, the nonpaged and paged-pool system look-aside lists are stored in the KPRCB.

EXPERIMENT: Viewing the KPCR and KPRCB

You can view the contents of the KPCR and KPRCB by using the !pcr and !prcb kernel debugger commands. If you don’t include flags, the debugger will display information for CPU 0 by default; otherwise, you can specify a CPU by adding its number after the command (for example, !pcr 2). The following example shows what the output of the !pcr and !prcb commands looks like. If the system had pending DPCs, those would also be shown.lkd> !pcr KPCR for Processor 0 at 81d09800: Major 1 Minor 1 NtTib.ExceptionList: 9b31ca3c NtTib.StackBase: 00000000 NtTib.StackLimit: 00000000 NtTib.SubSystemTib: 80150000 NtTib.Version: 1c47209e NtTib.UserPointer: 00000001 NtTib.SelfTib: 7ffde000 SelfPcr: 81d09800 Prcb: 81d09920 Irql: 00000002 IRR: 00000000 IDR: ffffffff InterruptMode: 00000000 IDT: 82fb8400 GDT: 82fb8000 TSS: 80150000 CurrentThread: 86d317e8 NextThread: 00000000 IdleThread: 81d0d640 DpcQueue: lkd> !prcb PRCB for Processor 0 at 81d09920: Current IRQL -- 0 Threads-- Current 86d317e8 Next 00000000 Idle 81d0d640 Number 0 SetMember 1 Interrupt Count -- 294ccce0 Times -- Dpc 0002a87f Interrupt 00010b87 Kernel 026270a1 User 00140e5e

You can use the dt command to directly dump the _KPCR and _KPRCB data structures because both debugger commands give you the address of the structure (shown in bold for clarity in the previous output). For example, if you wanted to determine the speed of the processor, you could look at the MHz field with the following command:lkd> dt nt!_KPRCB 81d09920 MHz +0x3c4 MHz : 0xbb4 lkd> ? bb4 Evaluate expression: 2996 = 00000bb4

On this machine, the processor was running at about 3 GHz.

Перейти на страницу:

Похожие книги