Geoff Chappell, Software Analyst
If only for now, this article is specific to 32-bit Windows (i386 or x86).
The MISMATCHED_HAL bug check reports that the loader, kernel and HAL disagree about their combination.
Bug Check Code | MISMATCHED_HAL |
1st Argument | case number (see notes for details) |
2nd Argument | in some cases, a vital parameter as actually found; otherwise depends on case |
3rd Argument | in some cases, what was expected for the parameter from the 2nd argument;
otherwise depends on case |
4th Argument | 0 typically; but depends on case |
This bug check is mostly raised by the HAL but can also be raised by the kernel. Half a dozen different cases are indicated by the first argument. The bug check seems to have started with a consistent scheme in which the 2nd and 3rd arguments describe respectively what was found and what was expected for a parameter that corresponds to the 1st argument. However, additions have not kept to the pattern, and since at least one case is interpreted very differently in different Windows versions, the cases are here taken separately.
A 1st argument of zero is merely incidental, the bug check having been raised (whether by the kernel or HAL) without providing arguments:
Bug Check Code | MISMATCHED_HAL |
1st Argument | 0, apparently not intended as anything specific |
2nd Argument | 0 |
3rd Argument | 0 |
4th Argument | 0 |
In version 4.0 and higher, the kernel raises case 0 if ever the HAL function HalSystemVectorDispatchEntry returns anything other than 0 or 1. No known HAL implements this function to return anything else. Indeed, only one known HAL can return anything other than 0. (This is HALSP.DLL, which is last known in version 5.1.)
The HALCBUS and HALCBUSM variants raise case 0 if they are unable to find the identifying string “Corollary” in the BIOS. These variants are not known from later than version 4.0.
Cases 1 and 2 cover the KPRCB, which is an important structure on which the kernel and HAL must agree. Both these cases of the bug check are supported from at least version 3.51.
Bug Check Code | MISMATCHED_HAL |
1st Argument | 1, indicating mismatched MajorVersion in KPRCB structure |
2nd Argument | MajorVersion from KPRCB |
3rd Argument | 1, presumably as HAL’s expected MajorVersion |
4th Argument | 0 |
The MajorVersion is the word at offset 0x02 in the KPRCB. All known HALs require it to be 1. All known kernels set it to 1, too, which means that this case of the bug check cannot occur in real-world practice.
Considering that KPRCB is an undocumented structure, it is striking that it has maintained the same version number for the whole history of Windows. Of course, the KPRCB has not kept to one layout for all this time, and the usefulness of this bug check as a defence against a mismatch of expectations between kernel and HAL is dubious.
Bug Check Code | MISMATCHED_HAL |
1st Argument | 2, indicating mismatched BuildType in KPRCB structure |
2nd Argument | BuildType from KPRCB |
3rd Argument | 0, presumably as HAL’s expected BuildType |
4th Argument | 0 |
The BuildType is the word at offset 0x12 in the KPRCB. It has the 0x01 bit set for a checked build and the 0x02 bit set for a single-processor build. Different HAL variants, all inspected only as free builds (the days when Microsoft supplied checked builds on disk as part of an MSDN subscription seem to be long gone), have different expectations:
Requirement | HAL Variants |
---|---|
0x01 bit clear | HAL, HAL486C, HAL98APC, HAL98TMR, HAL98UP, HALAACPI, HALACPI (before version 6.0), HALAPIC and HALMCA |
0x01 and 0x02 bits clear | HAL98MP, HALACPI (in version 6.0), HALBORG, HALMACPI, HALMPS, HALMPSM, HALNCR, HALOLI, HALSP and HALWS3 |
equals zero | HALAST, HALCBUS, HALCBUSM and HALWYSE7 |
Since a multi-processor kernel can run safely (if less efficiently than would a single-processor kernel) on a single-processor system, a single-processor HAL can tolerate a multi-processor kernel. The HALs that require only that the 0x01 bit be clear are single-processor HALs. By contrast, a multi-processor HAL must have a multi-processor kernel.
The discrepancy about testing for bit flags or for particular values may tell something about the process of HAL adaptation. Early documentation, such as the Knowledge Base article Descriptions of Bug Codes for Windows NT (number 103059, apparently no longer available at Microsoft’s website), presented the build type as an enumeration with just three values:
Later documentation has four values, with interpretation in bit flags being obvious, but what does Microsoft define in the source code that is surely available to the manufacturers who pay for some sort of HAL adaptation kit? Note that none of the HALs that require BuildType to equal zero survive into version 5.0.
Before version 6.0, case 3 of the bug check indicates that the bus type as learnt from the loader is not acceptable to the HAL.
Bug Check Code | MISMATCHED_HAL |
1st Argument | 3, indicating mismatched bus type |
2nd Argument | bus type from loader |
3rd Argument | bus type expected by HAL |
4th Argument | 0 |
The bus type is passed from the loader to the kernel and HAL as the byte at offset 0x60 (in 32-bit builds) in the LOADER_PARAMETER_BLOCK structure (whose address the kernel keeps in an exported variable named KeLoaderBlock). The known values are:
However, the only bus type that any HALs are known to care about is the Micro Channel. The HAL, HAL486C, HAL98TMR, HAL98UP, HALACPI, HALCBUS, HALOLI and HALSP variants all reject the Microchannel bus (reporting 0 for the 3rd argument), but HALCBUSM, HALMCA and HALNCR insist on it. Curiously, though HALMPS and HALMPSM differentiate themselves on MCA support, neither raises this bug check for a mismatched bus type. The MCA-specific HALs were all discontinued in version 5.0.
In version 6.0 only, case 3 is instead raised by the kernel to report a mismatch with the loader. The LOADER_PARAMETER_EXTENSION is a structure whose address is provided as the Extension member (at offset 0x58 in 32-bit builds) of the LOADER_PARAMETER_BLOCK.
Bug Check Code | MISMATCHED_HAL |
1st Argument | 3, indicating mismatched LOADER_PARAMETER_EXTENSION structure |
2nd Argument | Size from LOADER_PARAMETER_EXTENSION |
3rd Argument | MajorVersion from LOADER_PARAMETER_EXTENSION |
4th Argument | MinorVersion from LOADER_PARAMETER_EXTENSION |
The LOADER_PARAMETER_EXTENSION is shared with the HAL since at least version 5.2, such that agreement about its layout is surely a good thing to check. The extension is deemed mismatched if its Size (the dword at offset 0x00) is less than 0x7C, its MajorVersion (the dword at offset 0x14) is not 6, or its MinorVersion (the dword at offset 0x18) is not 0. Checking all three of Size, MajorVersion and MinorVersion is needed in general since the LOADER_PARAMETER_EXTENSION structure has changed in size without changing in version numbers.
Version 6.1 makes a new bugcheck, LOADER_BLOCK_MISMATCH, for the kernel’s disagreement with the loader for either the LOADER_PARAMETER_BLOCK or LOADER_PARAMETER_EXTENSION.
In versions 5.0 up to but not including 6.0, case 4 of the bug check reports an inability to find the root of the ACPI tables.
Bug Check Code | MISMATCHED_HAL |
1st Argument | 4, indicating |
2nd Argument | 0xAC31 |
3rd Argument | 0 or 1 |
4th Argument | 0 |
Case 4 is raised only by HALAACPI, HALACPI and HALMACPI. The significance of the 2nd argument is unknown. The 3rd argument can be 0 or 1 in version 5.0 to differentiate two conditions:
The 3rd argument is only 0 in version 5.1 and higher. These versions recognise both the RSDT and XSDT signatures and explain a bad signature by writing “Bad RSDT pointer” to the display before raising the bug check. The version 5.2 from Windows Server 2003 SP1 drops the first condition, so that although its occurrence may (eventually) be a problem elsewhere, it does not cause the bug check.
Not only do the HALAACPI, HALACPI and HALMACPI in versions 5.0 and higher need to find the root of the ACPI tables. They must have specifically a Multiple APIC Description Table (with APIC as its signature). Without one, they halt the system at startup, displaying the message
HAL: No ACPI APIC Table Found HAL: This HAL.DLL requires an MPS version 1.1 system Replace HAL.DLL with the correct hal for this system The system is halting
Even if the APIC table is found, HALAACPI and HALACPI raise case 6 of the MISMATCHED_HAL bug check unless the APIC table reports a PC-compatible configuration:
Bug Check Code | MISMATCHED_HAL |
1st Argument | 6, indicating APIC table has PCAT_COMPAT bit (0x01) clear in flags (offset 0x28) |
2nd Argument | 0 |
3rd Argument | 0 |
4th Argument | 0 |
The MISMATCHED_HAL bug check can occur in version 3.51 and higher.
Microsoft’s documentation in the Windows Driver Kit (WDK) for Windows Vista, dated January 2007, and in the contemporaneous Debugging Tools for Windows, lists only cases 1, 2 and 3, and case 3 is described only in its new meaning.