IBM PC-AT‎ > ‎Windows‎ > ‎Boot Process (detailed)‎ > ‎

Phase 5 - NTLDR or BOOTMGR

At this point the file system boot sector has loaded (or began loading) NTLDR or BOOTMGR. These files do not have an extension, are normally hidden, and must reside in the root directory. If you receive an error like NTLDR (or BOOTMGR) IS MISSING, then you know that at least the file system boot sector loaded (Phase 4). If you get a more generic error, like MISSING OPERATING SYSTEM, the problem is likely a corrupt MBR (pointing to the wrong sector for the file system) or perhaps the boot sector of the file system can not be read (corrupt data, ancient BIOS, or ancient MBR code).

I haven't disassembled the file system boot sector code to be sure, but if it is like some of the older Microsoft operating systems, it may only load the first few sectors of NTLDR / BOOTMGR before jumping into the partially-loaded code to finish. This is because the boot sector is only 512 bytes (and not all of those bytes are available for code).

BOOTMGR is the new “initial” loader with Windows Vista, 2008, and 7 (and probably 8). NTLDR is used in prior NT-based Windows (2003, XP, 2000, NT4). I describe both here because NTLDR is basically BOOTMGR + WINLOAD (see Phase 6 for Winload). I described both here because they perform the same function.

Both NTLDR and BOOTMGR begin with a "real mode stub" which switches the CPU from 16-bit "real" mode to 32-bit protected mode; I haven't disassembled the 64-bit versions or read much about what they do... if they are like Windows PE then they run in 32-bit mode. Once protected mode in activated, they try to load the "boot information". If an error occurs in this phase, you will usually get a relatively informative message. At least a name and error number (so you can look it up if the meaning isn't obvious).

NTLDR first looks for a text file called BOOT.INI in the root directory.  If it is not found, it defaults to either C:\WINNT\SYSTEM32 (Windows 2000 and earlier) or C:\WINDOWS\SYSTEM32 (Windows XP and newer).  This implies you need the BOOT.INI file if you have mutiple versions of Windows.  The following assumes that a Windows NT-style operating system is selected to boot (i.e., not Windows 9x, DOS, Linux, etc.).  NTLDR reads a file called NTDETECT.COM in the root directory and "calls" it (the code runs and then execution resumes in NTLDR).  If the BOOT.INI file references a SCSI device (or presumably if NTDETECT discovers one), another file that it loads is called NTBOOTDD.SYS (which must be in the root directory as well).  According to Microsoft, this file is a copy of the SCSI device driver used when Windows was installed (for example, a copy of Aic78xx.sys or Aha154x.sys, depending on your hardware).  This implies your system will fail to boot if you change SCSI controllers.  If you're using an IDE / SATA drive, you should be able to boot if NTBOOTDD.SYS is missing or corrupt.  (Well I can delete it and my system still boots up.)  Anyway, if the BOOT.INI is corrupt, it is fairly easy to fix with almost any text editor (the only problem may be writing to an NTFS file system).
 
BOOTMGR will look for a registry hive called BCD in a directory called BOOT.  If the BCD file is corrupt, you need to run a special Windows utility called BCDedit to change it. Well it is a registry hive, so you could use registry tools to fix it, if it were documented. Microsoft's documentation of BCDedit is pretty poor, and non-existant when it comes to the BCD data file! If you don't have the Windows installation DVDs (that allow you to run recovery console), you may be able to start the recovery console by pressing a special key during boot-up (this depends on the OEM adding the option and often that no changes have been made to the partition table).  If you can't access the recovery console, the easiest thing is probably to install the hard drive in another computer that is running Windows Vista/7/8. You can also do this with Windows 2000/XP but you will need to also download the 32-bit version of BCDedit. Another option is to download and burn a Windows Vista PE CD (yes a single CD image and not a ginormous DVD set).
 
For BOOTMGR, there is also a subdirectory under BOOT called FONTS.  These contain true-type fonts for multiple languages (strangely, even if only English is installed).  Presumably the correct one is selected based on the language setting in the BCD hive.  I haven't had a problem with missing / corrupt fonts in the BOOT directory, so I don't know what symptoms would appear if these were missing or corrupt.  Also, have no idea what would happen if the BCD hive failed to load.
 
Once the data is loaded, the fun begins!  The BOOT.INI and BCD files both contain a set of global options.  For BOOT.INI these are under the section [boot loader]. For BCD, these are under the heading {bootmgr} -- and curly brackets are part of the name. The global options include things like default selection and delay time (TIMEOUT).

The delay time is a bit deceptive, in that NTLDR / BOOTMGR should wait for X seconds (whatever delay) before loading the default operating system. However if only one entry is listed (typical unless you have a “dual-boot” system) then there is no message or delay. Very annoying from a trouble-shooting standpoint. Playing around with this, I noticed that I could set an insane delay of 9999 seconds, and BOOTMGR ran just fine (and with 2+ entries it really counts down all them seconds), although Windows' computer managment / start-up options will give an error (Please enter 99 seconds or less).

As far as I can tell, BOOTMGR only lists the first four (4) options in the BCD file, and NTLDR lists only the first eight to ten (8~10) options from BOOT.INI. (It's been a while since I played with it). For me, 4 options is ridiculously limited, but then again I ran out of options when 10 were available... can you say hexadecimal boot computer? Good; I knew you could!

Assuming NTLDR / BOOTMGR doesn't proceed automatically (i.e., actually shows its menu), the mere presence of the boot menu lets you know that your video card is working (at least VGA text mode), along with the keyboard, boot device, CPU and RAM. In contrast, imagine if no menu appears and it proceeds automatically... well if an error occurs and the system locks up or resets without giving an error (it happens) then you really don't know where to look: bad RAM ? bad MBR ? bad File System ? corrupt NTLDR / BOOTMGR ? Anway, if the boot menu does appear it may only display for a few seconds. If this happens and you want more time, you can press any cursor key to erase the count-down and give yourself infinite time.

For each entry in BOOT.INI you get to specify several things to NTLDR. First a description for the user. You can edit the file to make it say "hello world" which lets you know the system is reading from the correct disk/partition. Each entry is easy to identify in the BOOT.INI file so you don't really need a description. For BOOTMGR however, each entry (except the first/default) doesn't get an easy name, it gets an ugly GUID that only a programmer or CPU could love; a good description is imperative for BCD entries!

For each entry (typically only one, unless a "dual-boot" system), one important value is where to find the operating system... it is probably on the same disk / partition as BOOTMGR / NTLDR under a directory called Windows, but it could be someplace else. Now here is where the two diverge noticeably.
 
BOOT.INI will specify the OS with something like multi(0)disk(0)rdisk(0)partition(1)\WINDOWS. As far as I can tell, partition() refers to a 1-based partition number while the others are 0-based. If this seems weird, it is because partition(0) refers to the disk as a whole... I like to think of it as the MBR of the disk, and the partitions follow naturally. So partition(1) would normally be drive C, and partition (2) would be drive D, etc. Assuming there is only one hard drive. If there are two hard drives, and the second one has a partition marked active (bootable) in its MBR, then that partition may be labeled drive D and thus partition(2) of the main drive would be called E. If this is confusing, it is because Windows has a bizarre naming convention designed for DOS compatibility. The important thing is that the multi(0)disk(0)rdisk(0)partition(X) notation, although cumbersome, is quite definite.

The BCD file used by BOOTMGR, on the other hand, uses a secret internal naming scheme. This seems to be some hash of the hard drive’s vendor ID (for example, a hash of “WDC 300 GB R90210” if you had a Western Digital hard drive) plus the starting sector number of the partition. If you are looking at a hex dump of the BCD file, or looking at the keys using REGEDIT, then this hash + sector number is nearly indecipherable (much worse than the old multi(0)disk(0)rdisk(0)partition(X) format).

However, the BCDedit utility will display this as a drive letter of the currently running operating system; for example “DEVICE PARTITION=C:” In particular, it will show the wrong drive name of a foreign operating system. For example, you have two hard drives: both have Windows Vista installed and each one (when installed alone) boots up to the classic drive C (first partition). If you run BCDedit while running either alone, it will tell you the DEVICE for the {default} operating system is PARTITION=C:. Now install both hard drives. We'll assume the second/alternate hard drive is named D. The main hard drive is still named C. If you use BCDedit to examine the BCD file on the second hard drive, you may be surprised to discover that it has magically changed to PARTITION=D: (or whatever the second/alternate drive is now named). Well actually the BCD file on that disk has not changed at all! It is simply that the BCDedit utility is displaying a different name in place of the secret internal value. Microsoft does not document this at all (or else I missed it after much research).

So if using BCDedit with a second disk, just know that entries refer to what you see 'now' and not what will be seen when that drive is actually booted. For example, if you physically swapped drives (swapping boot device in the BIOS might work too) that other Windows will not boot up as drive D, because when it runs it will (probably) name itself drive C. Yeah, I guess that is confusing unless you experience it yourself. The bad thing about the BCD/BOOTMGR method is you don't really know what physical partition it is referring too. On the other hand, changing partitons and adding/removing drives will usually not cause the system to fail (this could be catastrophic in earlier versions of Windows).

Another troubleshooting note: the DEVICE listed for entries in the BCD file are active / valid entries... if you ever get a listing like UNKNOWN or BCDedit just aborts without warning, it generally means the UNKNOWN entry (or some entry that never started to display) is invalid. For example, deleting a partition may leave the BCD data referring to a sector which is not the start of a file system (presumably Windows updates the BCD when modify partitions, but maybe it fails sometimes); the same thing can happen if you relocate a partition on the same drive (Windows does not allow this [and now you know why] but some 3rd-party disk partitioning utilities do). It will always show UNKNOWN (or crash) if the drive has been physically removed from the system. In such cases, use BCDEDIT /SET {guid} DEVICE PARTITION=X: (where X is whatever the drive is called when you run BCDedit). You may have to delete the entry entirely.

Above I said the operating system would probably name itself drive C when it runs, even though it may appear as drive D (in Windows Explorer and BCDedit) when you have it installed as a second drive. However, there is a not-so-easy-to-set option in Windows setup that will you let specify any drive letter (well, probably not A or B). Which means when that operating system boots, it may consider itself drive K (for example), even if it is the first partition on a disk. So you can get weird naming behavior even if you have only one physical hard disk. If you are wondering how this works, it is a setting in the registry that tells Windows what to name the partitions. Each Windows installation gets its own registry so they can call themselves whatever they want (duplicate / inconsistent names). The default naming typically follows the DOS tradition, especially in a simple setup. But once you start multi-booting, with either multiple partitions, and especially multiple drives, things can get pretty hairy.

If you aren't confused yet, here is something else to ponder. There is a second setting (called OSDEVICE) under the same {guid} in the BCD file; Microsoft is absolutely terrible at explaining (or great at obscuring) the difference between OSDEVICE and DEVICE. These values are always identical on the systems I've tested / created. (They can be different, but I don't know what would happen). There is yet another DEVICE listed under {bootmgr}, but its meaning is more clear and described a little later.
 
Anyway, on the same line of a BOOT.INI entry or in a value called SYSTEMROOT of a BCD entry is the name of the Windows directory. Its importance is explained under Phase 6. This path is typically named "\Windows" (go figure) but on some systems it might be WINNT or something more creative.

There are several other options that may follow the path on an entry line of BOOT.INI (these are listed as various settings under the {default} / {guid} BCD entry). Useful examples include /DETECTHAL /NOGUIBOOT /SOS /SAFEBOOT:MINIMAL /BOOTLOG /NOCRASHAUTOREBOOT /BASEVIDEO /ONECPU. A few of the names in BCDedit are different than those listed in BOOT.INI. The settings in the BCD file are translated into equivalent BOOT.INI strings and passed to the kernal. See Geoff Chappell’s excellent chart for how BOOTMGR maps BCD settings into BOOT.INI strings.

One of the new options exclusive to BOOTMGR is /OPTIONSEDIT. When set to true, the user gets to edit the "command line" before things progress to Phase 7. This is a lot like how GRUB and LILO will let you pass options to the kernel when booting Linux. If you try this, you will see the data passed by BOOTMGR / WINLOAD to the kernel is identical to the line that would appear in a BOOT.INI file if NTLDR were used, except only the options after the device and path. In other words, you can edit the string to specify any kernel file (the default is ntoskrnl.exe) or other options (/DETECTHAL etc.) but it has to be in the same path and on the same disk as specified by the secret BCD data encoding.

Trouble-shooting note: setting OPTIONSEDIT to true allows you to pause the progress of BOOTMGR in the next phase even though it would normally continue without waiting in the case of only 1 entry described previously (unfortunately it still won't pause this phase).

A critical new entry for BOOTMGR is listed under the {default} / {guid}. It is the value of PATH. No this is not the path to Windows, it is the path to WINLOAD. (This is not present in BOOT.INI because NTLDR = BOOTMGR + WINLOAD.) The typical setting is “\Windows\System32\winload.exe” (even on 64-bit platforms). See Phase 6 for details.  Note I was unable to find any good web pages for you that discuss it directly in detail... it seems every one relates to errors or viruses or only gives a one-paragraph discription!

One more option unique to BOOTMGR is a setting called DEVICE under the section called {bootmgr}. Now most options under {bootmgr} act as global settings for any choice in the boot menu; and each choice has its own DEVICE setting (and the mystery OSDEVICE setting), so you may wonder what this DEVICE refers to... it refers to the boot sector of the file system from Phase 4. But since we already completed that, why is it in the BCD store? That part of the BCD store is designed for Extensible Firmware Interface (EFI) devices that use a boot method different from IBM PC-AT compatibles. In fact, BOOTMGR itself is said to duplicate the functionality of EFI, but because I don't have any EFI hardware I can't really comment.

Eventually a boot entry is "selected", either by default (no choice / only 1 entry), or display timeout, or user selection of either RETURN/ENTER to continue or F8/F10 to see advanced options. At that point the system moves to Phase 6.
 
Trouble-shooting note: several people (including Microsoft) recommend saving the BCD file before making any changes to it.  I agree this is a wise precaution; however if you actually try to copy the BCD file, you may get an error (on some versions of Windows) like "FILE IN USE / NOT ACCESSIBLE".  If that happens, try opening REGEDIT and navigate to the key HKEY_LOCAL_MACHINE\BCD000001 and then select File\Unload Hive... Once the Windows registry is not actively "holding" the BCD hive you should be able to copy it.

© H2Obsession, 2014
Comments