阅读:1091回复:0
蓝屏内幕3
Where do Blue Screens Come From?
Blue Screen’s are NT’s way of saying that something has gone terribly wrong and that the system has been stopped either because NT itself is baffled, or continuing may lead to data loss or corruption. The screen is thrown with a call to one of two functions, KeBugCheck(...), or KeBugCheckEx(...), both of which are exported for use by device drivers and file systems (Figure 2). VOID KeBugCheck( IN ULONG BugCheckCode ); VOID KeBugCheckEx( IN ULONG BugCheckCode, IN ULONG BugCheckParameter1, IN ULONG BugCheckParameter2, IN ULONG BugCheckParameter3, IN ULONG BugCheckParameter4 ); Figure 2 -- KeBugCheck and KeBugCheckEx prototypes Both bug check calls take a BugCheckCode parameter. This parameter is also known as a STOP code, and generally categorizes the reason for the system halt. KeBugCheckEx(...) takes 4 additional parameters that are simply printed on the Blue Screen along with the stop code. These parameters have pre-defined meanings for some standard stop codes (some of which I’ll describe later), but a device driver can use its own stop code numbers with its own definitions for the parameters. KeBugCheck(...) does nothing more than call KeBugCheckEx(...) with the 4 parameters set to 0. The first thing KeBugCheckEx(...) does is disable all interrupts by calling KiDisableInterrupts(...). Then it pops the machine into Blue Screen mode and dumps the stop message (\"*** STOP 0x0000000A:…\" in Figure 1). It accomplishes both of these operations with one call to HalDisplayString(...). HalDisplayString(...) takes one parameter, which is a string to print to the Blue Screen. It checks to see if the system is already in Blue Screen mode and if its not, it uses the firmware to switch it. Then it dumps the string argument into text-mode video memory at the current cursor position, which it keeps track of across calls. Thus, HalDisplayString(...) can be used in your own driver to throw \"custom\" Blue Screens, or to print informational messages to the Blue Screen that is displayed as the system starts (e.g. from DriverInit of a system-start driver). Unfortunately, if you call HalDisplayString(...) after the system is past the initial Blue Screen, there is no way to restore the screen to its previous mode (you’re then stuck in the Blue Screen). KeBugCheckEx(...) next calls KeGetBugMessageText(...), a function that translates a stop code to its text-equivalent by using an internal table of stop names. You can see the complete set of system pre-defined stop codes and their associated text in the bugcodes.h file in the DDK. Because most of us continuously see the same 4 or 5, you might be surprised to learn that there are currently about 150 defined stop codes. At this point KeBugCheckEx(...) calls any Bug Check handlers that drivers may have registered. A handler is registered by calling KeRegisterBugCheckCallback(...), and its purpose is usually to fill in a buffer (allocated by the caller of the register routine) with device state that can be examined inside of WinDbg when debugging a crash dump. Bug Check callbacks are also useful if the device your driver is controlling must be shut off if the system fails (a 2000-pound robotic arm is a good example). You can have the driver’s callback twiddle ports on the device in order to disable it. Next, the system calls KeDumpMachineState(...), which dumps the rest of the text on the screen. KeDumpMachineState(...) first tries to interpret each of the 4 parameters that were passed to KeBugCheckEx(...) as a valid address within a loaded module, and stops when it can resolve one. It uses the internal function KiPcToFileHeader(...) to do this. The information KiPcToFileHeader(...) returns for the first parameter that it successfully resolves, is printed immediately following the text form of the stop code, and includes the base address of the module and the module’s name. Thus, an address parameter can be any of the 4 KeBugCheckEx(...) parameters. I’ll save an informative description of the stop codes for later. The rest of the screen is divided into three areas (not including the message about contacting your administrator). The first is the CPUID area, below that is the loaded driver area, and at the bottom is a stack trace. The CPUID area of the Blue Screen includes the CPUID, the IRQL setting at the time the Blue Screen is being drawn (on standard x86 HALs this will always be 0x1F |
|
最新喜欢:![]()
|