The Windows NT 6 boot process

This Frequently Given Answer uses Microsoft's terminology for boot and system volumes.

You've come to this page because you've asked a question similar to the following:

What is the Windows NT version 6.x boot process ?

This is the Frequently Given Answer to such questions. (It is not the DOS-Windows boot process.) It covers both the Windows NT 6.0 ("Windows Vista" and "Windows Server 2008") boot process and the Windows NT 6.1 ("Windows 7" and "Windows Server 2008 R2") boot process, which are, as the 6.x version numbering implies, largely the same.

Up to the point that the Windows NT 6 boot manager is loaded, the Windows NT 6 bootstrap process differs between systems that use EFI machine firmware and systems that use IBM PC compatible machine firmware. From that point onwards, the process is the same: the Microsoft boot manager loads and runs the Windows NT 6 boot loader, which loads and runs the Windows NT 6 kernel, which loads and runs the first user process.

How Windows NT 6's boot manager is loaded on systems that use EFI machine firmwares

The EFI bootstrap process is the subject of another Frequently Given Answer which describes it in detail.

On machines with EFI machine firmwares, the firmware is required to contain a boot manager, that loads and runs an EFI executable program, which is either a standalone utility program or an operating boot loader program. Microsoft's installation program adds an single entry to the EFI boot manager menu entitled "Windows Boot Manager" that names "\EFI\Microsoft\Boot\Bootmgfw.efi" as the EFI executable program to be run when that option is selected from the boot manager.

EFI executables are 32-bit PE-format executable programs that expect to run in protected mode, using the flat memory model and without paging enabled. The firmware itself places the processor in this mode before invoking any boot programs.

"\EFI\Microsoft\Boot\Bootmgfw.efi" is in fact another boot manager. Not content with simply using the EFI boot manager as designed, Microsoft employs its own boot manager as well.

This results in two boot managers being run on EFI systems. (As explained later, everything that Microsoft's boot manager does could have been done using the EFI boot manager. There is no real need for the second Microsoft boot manager on EFI systems.) Microsoft configures the EFI boot manager with a timeout of 2 seconds in order to, in Microsoft's words, "make it easier" for users. One has to think, though, that not reinventing this particular wheel in the first place and sticking with the EFI boot manager would also have made things easier for users, too.

How Windows NT 6's boot manager is loaded on systems that use PC98 or compatible machine firmwares

The bootstrap process on machines with old PC/AT and PC98 firmwares is the subject of another Frequently Given Answer which describes it in detail.

On machines with PC98 or compatible firmwares, the firmware loads the MBR from the first disc that it finds, which in turn loads the VBR of the first partition marked as "startable" that it finds.

As of Windows NT version 6.0, the bootstrap programs written by Windows NT to the MBR and the NTFS VBR use only the Phoenix/IBM/Microsoft EDD extensions to INT 13h. The code to use the old firmware API was completely removed. As such, Windows NT 6.0 and later cannot be bootstrapped on old PC/AT machines with IBM PC compatible firmwares. The PC98 specification mandated firmware support for these extensions.

This VBR loads and runs the Windows NT 6 boot manager, which is required to be stored as a file named bootmgr in the root directory of the system volume.

Unlike on EFI systems, IBM PC compatible firmwares execute VBRs as real mode programs using 16:16 addressing. It is up to the boot loaders themselves to switch the processor into protected mode if that is required.

The Microsoft boot manager therefore contains a 16-bit stub program, prepended to the boot manager proper (which is a PE-format 32-bit executable that follows the stub program), that switches the processor into 32-bit, flat memory model, protected mode before invoking the boot manager proper. Essentially, the real mode stub sets up the same environment that would occur if EFI firmware had invoked the boot manager from the PE-format executable directly. The stub initializes mode switching function call thunks that map (a subset of) the 32-bit protected mode machine firmware services that are provided on EFI systems to the 16:16 real mode machine firmware services provided by the actual IBM PC compatible firmware.

How Windows NT 6's boot loader is invoked by Windows NT 6's boot manager

Once Microsoft's boot manager is running, the bootstrap process for EFI firmware and IBM PC compatible firmware machines is largely the same.

Microsoft's boot manager reads a Boot Configuration Data file. The file is formatted in the same way as the Windows NT 6 registry hives are. Other BCD files (which Microsoft terms "BCD stores") are allowed, but this one is required and is the one that is read by the Windows NT 6 boot manager. Microsoft terms it the "system store".

The Boot Configuration Data file comprising the "system BCD store" is located in different places according to the type of the machine firmware:

That the location differs according to firmware type is the reason that it is difficult to switch an installed Windows NT 6 system between EFI firmware and IBM PC compatible firmware. (Microsoft explains that it is difficult in its documentation, but fails to explain that this is why it is difficult.) Switching requires that the system BCD store file be copied to the appropriate location.

The system BCD store contains a Windows-centric equivalent of the EFI boot manager configuration data. Everything that Microsoft's boot manager does can be done using the EFI boot manager directly:

The Windows NT 6 boot manager presents a menu to the user to select what to boot. (So on EFI systems users see two successive boot manager menu screens.) This menu comprises a list of Windows Boot Loader, Windows Resume Loader, Windows NTLDR, "boot application", and "boot sector" entries, each defined by its own data structure in the BCD file and listed in the Windows Boot Manager data structure.

The two relevant types of entry for bootstrapping Windows NT 6 itself are the Windows Boot Loader and Windows Resume Loader entries.

When a Windows Resume Loader entry is selected by the user, Microsoft's boot manager invokes the program winresume.exe to resume Windows NT 6 from hibernation. The system BCD store contains configuration information describing what winresume.exe should re-load.

When a Windows Boot Loader entry is selected by the user, Microsoft's boot manager invokes the program winload.exe to load the operating system proper ab initio.

How Windows NT 6 is bootstrapped by its boot loader

WINLOAD, the Windows Boot Loader, loads the Windows NT 6 kernel, boot-class device drivers, and system registry hive, just as NTLDR did in earlier versions of Windows NT.

WINLOAD is in fact capable of loading earlier Windows NT kernels. In early beta releases of Windows NT 6, before the advent of Boot Configuration Data, the boot.ini file was split in twain, with one section denoting operating systems that could be loaded via NTLDR and the other section denoting operating systems that could be loaded via WINLOAD. Beta testers discovered that both Windows NT version 5.10.2600 SP2 (i.e. Windows XP), and Windows NT 5.20.3790 (i.e. Windows Server 2003) could be loaded by WINLOAD, as long as winload.exe was copied to the System32 directory on the target boot volume.

WINLOAD is simpler than NTLDR, however. NTLDR implements a "dual boot" system, parses boot.ini, implements hibernation resume, and presents a boot menu to the user before actually performing the nitty-gritty of loading the operating system. With WINLOAD, all of those tasks either have already been performed by a boot manager or are the purview of other programs such as WINRESUME. WINLOAD therefore only performs those functions of NTLDR that involve actually loading the operating system.

WINLOAD doesn't even have to switch into protected mode. NTLDR is (on 32-bit x86 systems) invoked in real mode by the Volume Boot Record code. It thus comprises a real-mode stub executable, prepended to the loader proper, that switches into 32-bit, flat memory model, protected mode and then invokes the loader proper (stored as PE-format executable in the remainder of the program image file). This is unnecessary with WINLOAD. Either the EFI firmware or the real-mode stub prepended to \Bootmgr has already switched the processor into protected mode.

WINLOAD simply loads the operating system kernel, system32\ntoskrnl.exe, the hardware abstraction layer, system32\hal.dll, the contents of the system registry hive, system32\config\system, all of the "boot" class device drivers, and any kernel-mode DLLs imported by any of the aforementioned, into memory.

WINLOAD loads the system registry hive first. Immediately after doing so it verifies its own in-memory executable image against a digital signature held in a digital signature catalogue file, system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\ If this check fails, WINLOAD will halt unless kernel debugging is enabled.

WINLOAD then loads the operating system kernel, the hardware abstraction layer, and all kernel-mode DLLs that they import. If kernel debugging is enabled, in addition WINLOAD loads one of several debugging libraries, which are kernel-mode DLLs that provide the debug kernel with library routines to communicate with the kernel debugger through a specific communications device. These files are system32\kdcom.dll, system32\kd1394.dll, and system32\kdusb.dll, which enable kernel debugging via an RS232 serial port, an IEEE 1394 serial port, or a USB serial port, respectively.

WINLOAD checks the image files for all of these against the digital signatures held in the aforementioned digital signature catalogue. WINLOAD in fact checks all image files — kernel, HAL, DLLs, and device drivers — that it loads, as it loads them. Digital signature checking is done by the code that loads image files into memory. All images must pass the digital signature check, with a signature that is traceable back to by a known Root Certification Authority (exactly 8 of which — 7 Microsoft and 1 Verisign — are hardwired directly into the signature checking code). WINLOAD contains no code to enable the revocation of any certificates.

If the check fails, WINLOAD will halt unless kernel debugging is enabled. Even if kernel debugging is enabled, WINLOAD will halt if one of a small fixed set of image files (winload.exe, ntoskrnl.exe, hal.dll, bootvid.dll, tpm.sys, ksecdd.sys, clfs.sys, ci.dll, kdcom.dll, kdusb.dll, kd1394.dll, and spldr.sys) fails the check.

WINLOAD then scans the registry, in particular the HKEY_LOCAL_MACHINE\SYSTEM\Services key, for the configured device drivers. It loads all of the device drivers that are in the "boot" class (SERVICE_BOOT_START) into memory, which again involves checking digital signatures.

WINLOAD then enables paging.

Finally, WINLOAD passes control to the operating system kernel.

How Windows NT 6's kernel initializes

The Windows NT 6 kernel performs the usual Windows NT kernel initialization steps, that are largely unchanged from Windows NT version 3.1:

  1. Request the HAL to initialize the interrupt controller.

  2. Initialize the Memory Manager, the Object Manager, the Security Reference Monitor, and the Process Manager.

  3. Request the HAL to enable interrupts.

  4. Start all non-boot CPUs.

  5. Reinitialize the Object Manager.

  6. Initialize the "Executive".

  7. Initialize the "Microkernel".

  8. Reinitialize the Security Reference Monitor.

  9. Reinitialize the Memory Manager

  10. Initialize the Cache Manager.

  11. Initialize the Local Procedure Call system.

  12. Initialize the I/O Manager. Initialization of the I/O manager initializes all of the pre-loaded, "boot" class, device drivers.

  13. Initialize the Process Manager.

The operating system kernel then scans the registry, the in-memory copy passed to it by WINLOAD, for the configured device drivers. It loads and all of the device drivers that are in the "system" class.

The kernel checks the digital signatures of all of the image files from which it loads device drivers, using routines exported from ci.dll, the kernel-mode DLL that provides a set of "code integrity" library functions. (Much of the content of ci.dll is exactly the same cryptographic code that is statically linked into winload.exe, including the 8 hardwired Root Certification Authorities.)

The kernel finally invokes the first user process, the so-called Session Manager Subsystem (SMSS).

The user-mode initialization in Windows NT 6

User-mode initialization involves several processes, executing in parallel and acting in concert. The first of these is the SMSS. This spawns other processes, which in their turn spawn yet other processes still. All processes run under the aegis of the "Local System" user account. (If that account is ever denied execute rights to the program image files for these various processes, the system will fail to initialize.)

The Session Manager Subsystem process' rôle in initialization

The SMSS process uses the native kernel API and manages sessions and subsystems (e.g. the Win32 subsystem, the 16-bit OS/2 subsystem, and the POSIX subsystem).

The initialization tasks performed by the SMSS are:

  1. The SMSS creates its LPC port, \SmApiPort, more on which later.

  2. The SMSS hand-crafts its initial environment, including the SAFEBOOT environment variable if the system has been booted into "Safe" mode. These environment variables are inherited by the "BootExecute" processes that SMSS later spawns.

  3. The SMSS sets up any "DOS device" names specified in the CurrentControlSet\Control\Session Manager\DOS Devices key in the system Registry.

    Note: Contrary to popular wisdom, these device names do not include "COM1", "LPT1", and so forth. Those are created by the serial port and printer device drivers themselves, when their AddDevice() entrypoints are called. The DOS device names created by SMSS are the generic names, that Windows NT has inherited from the standard built-in MS-DOS devices, such as "AUX", "NUL", and "PRN".

  4. The SMSS runs any boot-time programs specified by the BootExecute value beneath the CurrentControlSet\Control\Session Manager key in the system Registry. SMSS runs these programs synchronously, waiting for them to complete before proceeding.

  5. The SMSS executes any pending file/directory renaming or deletion operations that have been listed in the system Registry (under CurrentControlSet\Control\Session Manager\PendingFileRenameOperations or CurrentControlSet\Control\Session Manager\PendingFileRenameOperations2) to be executed when the system next initializes.

  6. The SMSS initializes additional page files, as configured by the system Registry settings under CurrentControlSet\Control\Session Manager\Memory Management\PagingFiles

  7. The SMSS mounts the registry hive files. When SMSS mounts the system hive, the kernel merges into it the in-memory copy of the system registry hive that was loaded by WINLOAD, so that additions and updates to the system portion of the registry (but not deletions) that were made earlier in the boot process before the hive was mounted are preserved.

  8. The SMSS reads a process environment template stored in the Registry (each environmement variable template stored as a value beneath HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment) and augments its hand-crafted environment from it. These environment variables are thus inherited by every process that SMSS spawns from this point onwards.

  9. The SMSS runs any boot-time programs specified by the SetupExecute value beneath the CurrentControlSet\Control\Session Manager key in the system Registry. SMSS runs these programs synchronously, waiting for them to complete before proceeding. Normally, there aren't any such programs specified.

  10. The SMSS reads the subsystem processes to start for sessions from the values beneath the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Subsystem key in the registry.

    The SMSS reads the program image file name of the WININT process to start for session 0 from the S0InitialCommand value beneath the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager key in the registry. By default, this is system32\wininit.exe. The WINLOGON process' program image file name is, similarly, system32\winlogon.exe.

  11. The SMSS pre-loads "known DLLs" (so that they are always open, and thus will be faster to load into processes) that are specified by the values beneath the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs key in the Registry.

    On other operating systems, the pre-loading of DLLs is done by ad-hoc user processes that execute with normal user privileges. (Witness emxload on OS/2, for example.) Because the pre-loading of DLLs is done by a process running under the aegis of the local system user account and with Trusted Computer Base privileges, one must be very careful about what is added to the registry's list of "Known DLLs" on Windows NT.

  12. The SMSS works out what drive letter the boot volume has, by looking at the SystemPartition value beneath the HKEY_LOCAL_MACHINE\System\Setup key in the Registry, and calculating which drive letter it corresponds with.

  13. The SMSS starts up the subsystem processes for sessions 0 and 1 (and any further sessions specified by the NumberOfInitialSessions value in the registry) and runs their respective main user processes. In session 0, the SMSS runs an init process; in session 1 and above, it runs a logon process. Thus session 0 is a "WININIT" session and session 1 and above are "WINLOGON" sessions.

    Note: The init process is new to Windows NT 6. On prior versions of Windows NT the SMSS would create one session, session 0, with subsystem and logon processes. Much of what the init process does on Windows NT 6 would be handled by the session 0 logon process. This split is called Session 0 Isolation by Microsoft.

    The SMSS starts sessions by spawning copies of itself, whose sole duties are to start the processes for a single session and then simply exit. The reason that it does this is that there is insufficient parallelism in its code for starting sessions. Having multiple SMSS process each starting an individual session allows multiple sessions to start in parallel — an important consideration in a Terminal Services server, where there are a lot of sessions to be started at boot time. Using a single SMSS process would result in sessions being started sequentially. However: Quite why Microsoft resorted to spawning a wholly new child process rather than simply employing a separate thread within the main process to start each session, is unclear.

  14. The SMSS enters a loop waiting for LPC requests or for WININIT, WINLOGON, or CSRSS to terminate. Other processes may communicate with the SMSS using its LPC port (\SmApiPort) to invoke additional subsystem processes (such as the POSIX Subsystem) in a session, to create additional sessions (which would have their own subsystem and logon processes), or to shutdown the system. If WININIT, WINLOGON, or CSRSS ever terminate, SMSS crashes the system. (See the CSRSS Backspace Bug.)

BootExecute and SetupExecute processes

BootExecute processes and SetupExecute processes are spawned synchronously by SMSS. They are executed before any of the API subsystem processes (CSRSS, PSXSS, and so forth) or their kernel-mode counterparts have been invoked, so cannot be POSIX or Win32 process. They can only use the native Windows NT kernel API.

BootExecute processes, in particular, execute in a very limited environment indeed. They are executed before any initialization task that might have "touched" the boot volume has been performed. The registry hives haven't been initialized; the paging files haven't been created; nor have any pending file/directory renaming/deletion operations been performed. The environment variables haven't even been initialized from the template in the registry. So woe betide the BootExecute process that thinks that it can safely allocate more virtual memory than available physical RAM, for example.

SetupExecute processes at least have the environment initialized from the registry template, paging files enabled, and pending filesystem operations performed. However, at the point that they are executed, the "known DLLs" aren't loaded, the display is not in graphics mode, and no subsystems have been started nor sessions initialized.

Both BootExecute and SetupExecute processes execute under the aegis of the Local System user account, of course.

There's only one well-known SetupExecute process:

system32\setupcl.exe — the Windows NT phase 2 installation program

When Windows NT is first installed onto a volume, the installation program creates the SetupExecute key in the Registry, directing SMSS to invoke this program. Phase 2 setup thus occurs before sessions are initialized.

There are several well-known BootExecute processes:

system32\autochk.exe — automatic CHKDSK

This is the same program code as chkdsk.exe, except that the latter is an ordinary Win32 program, whereas autochk has been compiled to use the native kernel API for its user interface.

system32\autoconv.exe — filesystem converter

This performs the conversion of the boot volume from FAT to NTFS during system installation. It has to be a BootExecute proces rather than a SetupExecute process because it has to be run before anything uses any files from the boot volume, which of course would both lock it and mount the FAT filesystem driver on it.

system32\autofmt.exe — automatic FORMAT

This is the same program code as format.exe, except that the latter is an ordinary Win32 program, whereas autofmt has been compiled to use the native kernel API for its user interface. This is used by the format command to schedule pending volume format operations against the boot volume (and other locked volumes). People have also used it to automatically format RAMdiscs at startup.

autontfs.exe — Diskeeper's NTFS defragmenter

This defragments volumes, such as the boot volume, that would be locked later in the boot process.

xmnt2002.exe — Partition Magic's batch update utility

This performs updates to the partition table that involve the system volume, such as moving it or resizing it, which cannot happen after it is locked later in the boot process and which could not have been performed at the time that Partition Magic was initially run, for the same reason.

PDboot.exe — something by Raxio Software

Although it has KnowledgeBase articles explaining at length that the program is supposed to be listed as a BootExecute process, Raxio Software doesn't actually tell the world what this program does.

The Client-Server Runtime Subsystem process' rôle in initialization

The CSRSS process uses the native kernel API and implements the user-mode part of the Win32 subsystem. In Windows NT prior to version 4.0, it implemented the whole of the Win32 API, which was implemented wholly in user-mode. In Windows NT 6, only functionality such as console handling remains in CSRSS, most functionality having been moved to system32\win32k.sys. Several kernel-mode threads, created by win32k.sys, are also created in the CSRSS process.

CSRSS listens on an LPC port for Win32 API calls and handles them. It is the CSRSS process (in particular the winsrv.dll dynamic link library that it links to) that creates and processes messages for the GUI windows that represent Win32 "consoles". (Albeit that there is some jiggery-pokery that goes on with injecting console.dll and extra threads into other processes, when certain events occur.)

CSRSS never terminates. If it does, both SMSS and the Windows NT kernel notice. (The CSRSS process has the "critical process" flag set in its process object within the kernel.)

The Windows Init process' rôle in initialization

WININIT is a Win32 process that does all of the stuff that the first instance of WINLOGON used to do in prior versions of Windows NT, i.e. stuff that was more related to one-time overall system initialization than to per-session initialization and to user logon. The SMSS by default starts a WININIT process in session 0. There is no need for further WININIT processes.

WININIT spawns the Local Security Authority SubSystem process, using the system32\lsass.exe program image file, the Service Controller process, using the system32\services.exe program image file, and the Local Session Manager process, using the system32\lsm.exe program image file. In prior versions of Windows NT, these two would be managed by the first WINLOGON process, and if either process ever terminated, WINLOGON would initiate a system shutdown and restart. WININIT spawns these processes in Windows NT 6, and WININIT is not involved in the user logon and system shutdown mechanisms.

One new thing that WININIT does is to load wls0wndh.dll and register its (exported) Session0ViewerWindowProcHook function as a global window hook on the user desktop of session 0. This is the hook that recognizes when a session 0 process has (erroneously) created a window on the desktop. When invoked, it starts the UI0Detect service (with appropriate limits to prevent starting it if already starting or started).

The Windows Logon process' rôle in initialization

WINLOGON is a Win32 process that provides the user interface for logging on to, logging off from, locking, and unlocking a single session in the system, and that handles system shutdown requests. It manages the spawning of user processes (normally userinit.exe) when users log in, and the killing of user processes when users log out. The SMSS by default starts a WINLOGON process in session 1. The Terminal Services server requests SMSS to start further WINLOGON process in further sessions.

In prior versions of Windows NT, the first WINLOGON process would perform one-time overall system initialization actions. In Windows NT 6, this functionality is in WININIT. WINLOGON only performs per-session initialization, and the first WINLOGON process is not a special case.

WINLOGON first creates a "window station" to conceptually bind together one or more keyboards, mice, and displays, and various Win32 global properties to form the logical unit of interaction with a single user. (In Unix/Linux parlance this would be a "head".)

In this window station, WINLOGON then creates three desktops: the WINLOGON desktop, the user desktop, and the screen saver desktop. WINLOGON assigns an ACL to the WINLOGON desktop that prevents any process but itself from accessing that desktop. (It grants permissions to a unique security ID that is only included in its own process token and in no other.)

In prior versions of Windows NT, WINLOGON would load a GINA ("Graphical Identification aNd Authentication") dynamic link library. Various functions in the GINA would handle waiting for the Secure Attention Sequence (Control-Alt-Delete), displaying the various login/logout/lock/unlock dialogue boxes on the WINLOGON desktop, and even invoking the user process (userinit.exe).

In Windows NT 6, the GINA scheme has been replaced with a system of Credential Providers, which moves some of that functionality (in particular universal parts such as invoking the user process) into WINLOGON itself and simply separates out into DLLs the functionality of obtaining user credentials via some user interface and of performing user authentication with those credentials via the LSASS. WINLOGON even supports simplified credential providers, where the user interface comprises a set of text fields, handling most of the user interface work on behalf of such providers.

Credential Providers are DLLs that export COM interfaces: ICredentialProvider, ICredentialProviderCredential, ICredentialProviderCredentialEvents, ICredentialProviderEvents, and ICredentialProviderFilter. They are hosted within a COM server process, LogonIU, that is spawned by WINLOGON.

The Local Security Authority Subsystem process' rôle in initialization

The LSASS process creates an LPC port, and then enters a loop handling security requests, such as requests to verify a set of user credentials against a user account database, that come down that port. Requests arrive from WINLOGON processes, from the network logon service process, and from user processes that wish to perform user authentication.

The Service Controller process' rôle in initialization

The Service Controller process scans the registry for the configured device drivers and services. It loads all of the device drivers and services that are in the "auto" class. It then enters a loop listening on an LPC port waiting for requests to start and to stop services.

Further reading

© Copyright 2006,2011 Jonathan de Boyne Pollard. "Moral" rights asserted.
Permission is hereby granted to copy and to distribute this web page in its original, unmodified form as long as its last modification datestamp is preserved.