wimboot is a boot loader that is roughly analogous to Windows' pxeboot network boot program. It lets you fetch all the relevant files over HTTP or any other supported protocol, and hands over execution to bootmgr.exe, the Windows boot manager. This page details the wimboot architecture, an overview of bootmgr.exe operation, and troubleshooting tips.
When wimboot is executed, it sets up a boot-loader environment before handing over execution to bootmgr.exe, the Windows boot manager, which continues to boot Windows according to the supplied boot configuration data (BCD).
When wimboot runs, it first processes the command line parameters supplied to it. The following parameters can be used to change its behaviour:
rawbcd: Disable rewriting .exe to .efi in the BCD file.gui: Display graphical boot messages.pause[=quiet]: Show info and wait for keypress.index=n: Use WIM image index n.initrdfile: Ignored. For syslinux compatibility.
Much like the Linux kernel, wimboot will extract the CPIO archive supplied to it by iPXE. The CPIO archive can be constructed with iPXE via the imgfetch command, and each invocation should be on the form
imgfetch --name <somename> <uri> <somename>
This will fetch the file given by <uri> and make it available with the virtual filename <somename> in the CPIO archive supplied to wimboot. Multiple imgfetch commands can be used, one after another. The seemingly redundant <somename> statements are used to provide compatibility with both UEFI mode (--name <name>) and legacy BIOS mode (<name> as the first argument) at the same time.
NOTE: The virtual filename <somename> must be a flat filename without subdirectory components.
The files from the CPIO archive are made available in a virtual filesystem provided up by wimboot. Here's an example of how this works in practice:
imgfetch --name BCD http://.../test.bcd BCD imgfetch --name boot.sdi http://.../boot.sdi boot.sdi imgfetch --name boot.wim http://.../install.wim boot.wim
This fetches the three files, which will all – when wimboot executes – be made available at multiple locations in a virtual filesystem. The locations are as follows:
\\Boot\Boot\Fonts\Boot\Resources\Sources\EFI\EFI\Boot\EFI\Microsoft\EFI\Microsoft\Boot
So for any given file, say test.bcd, it will be made available with the filename BCD at all the locations given above:
\BCD\Boot\BCD\Boot\Fonts\BCD\Boot\Resources\BCD\Sources\BCD\EFI\BCD\EFI\Boot\BCD\EFI\Microsoft\BCD\EFI\Microsoft\Boot\BCD
In practice, this enables bootmgr.exe to read \Boot\BCD and related files, even if they were seemingly placed only in the root directory by the imgfetch command. This can avoid having to modify BCD files.
Once it's set up, the virtual filesystem is then mapped to a disk drive so that bootmgr.exe can identify and read files from it.
NOTE: The BCD file name must be simply BCD so that it can be found by bootmgr.exe; it searches only for the specific path \Boot\BCD.
NOTE: The boot.sdi and boot.wim paths must match the paths referred to in the BCD file. In other words, the BCD could refer to either boot.wim, \Boot\boot.wim, \Sources\boot.wim or any of the other recognized subdirs; they would all work. On the other hand, if the BCD refers to a path not covered by the virtual filesystem, like \Image\boot.wim, it would fail.
As wimboot reads each file from the CPIO archive, the file's virtual filename is matched against a list of special names to see if it needs special treatment:
bootmgr.exe: Set this as the file to execute at the end of the boot-loader initialization.bootmgr: Try to extract bootmgr.exe from this compressed bootmgr file, unless a bootmgr.exe was already supplied.*.wim: Try to extract bootmgr.exe from the static path \Windows\Boot\PXE\bootmgr.exe within the supplied WIM image, unless a bootmgr.exe was already supplied.
NOTE: The ability to extract bootmgr.exe from the WIM image was added to wimboot v2.2.0. It is a very convenient feature that lets you skip having to explicitly supply the bootmgr.exe file explicitly.
NOTE: If no bootmgr.exe is found, wimboot exits.
At the final stage of wimboot execution, it reads bootmgr.exe into memory and hands over execution to it.
On EFI platforms, a few details are changed:
wimboot can extract bootmgfw.efi from the supplied WIM image, using the path \Windows\Boot\EFI\bootmgfw.efi.wimboot automatically patches the BCD file to change any occurrence of .exe to .efi. This behaviour can be disabled by the rawbcd argument to wimboot.
When bootmgr.exe executes, it has the first-stage environment already set up for it, containing the virtual filesystem set up by wimboot. As it runs, it performs the following steps.
Refer to the Microsoft How Booting into a Boot Image Works documentation for some additional details.
bootmgr.exe first interacts with the virtual filesystem by trying
to read the BCD (Boot Configuration Data store) file from the hardcoded path \Boot\BCD.
The BCD file can come from a variety of sources, or it can be created from scratch or modified using the bcdedit.exe tool in Windows. See the troubleshooting section for more information.
Refer to the Microsoft Boot Process and BCDEdit documentation for some additional details.
Once the BCD is read, bootmgr.exe will try to read the files referred to by the BCD from the virtual filesystem, such as the stub ramdisk SDI (System Deployment Image) path, e.g. \Boot\boot.sdi, and the main WIM Windows Imaging Format) image, e.g. \Boot\boot.wim.
NOTE: The SDI image is typically always provided by various Windows versions and deployment tools as boot.sdi, which is a template ramdisk with no content. It does not change significantly and does not need any change or customizations applied to it.
NOTE: The WIM image is the main image, either extracted from the Windows installation medium, or containing custom content created by the user or some automated image creation/capture process.
Once the relevant files are read from the virtual filesystem, bootmgr.exe mounts the blank template SDI ramdisk and appends the WIM image to it.
With the SDI+WIM ramdisk mounted and ready, bootmgr.exe hands over execution to the ramdisk as if it were an actual disk. The loading routines will eventually hand over execution to \Windows\system32\winload.exe.
Several things can go wrong in the boot process, and the bootmgr.exe error handling and output is quite vague and ambiguous, making it hard to understand what the exact problem might be.
Some common error messages are listed below:
bootmgr.exe cannot find or read the BCD file:File: \Boot\BCD Status: 0xc000000f Info: An error occurred while attempting to read the boot configuration data.
bootmgr.exe cannot find or read the SDI file:Status: 0xc000000f Info: The boot selection failed because a required device is inaccessible.
bootmgr.exe cannot find or read the WIM image:Status: 0xc000000f Info: A required device isn't connected or can't be accessed.
The usual culprit is incorrect data in the BCD file, which causes bootmgr.exe to stall without knowing how to proceed. Incorrect data can typically be:
wimboot virtual file systems, such as \, \Boot, \Sources, etc.
By following the wimboot/bootmgr.exe execution chain, troubleshooting is made a bit easier:
wimboot version.imgfetch commands are successful.pause argument to wimboot to pause execution just after wimboot has printed some useful information about its initialization:imgexec wimboot pause
Below is an example output of imgstat showing the files that were retrieved, their sizes and their arguments. The arguments will map to the filenames as made available in the virtual filesystem set up by wimboot:
test.bcd : 12288 bytes "BCD" boot.sdi : 3170304 bytes "boot.sdi" install.wim : 404876823 bytes "boot.wim" wimboot : 34576 bytes [bzImage] [SELECTED] "pause=quiet"
An example output of the wimboot pause screen:
wimboot v2.4.1 -- Windows Imaging Format bootloader -- http://ipxe.org/wimboot Command line: "pause=quiet" Using BCD via 0x67925074 len 0x3000 Using boot.sdi via 0x67929078 len 0x306000 Using boot.wim via 0x67c30078 len 0x1821ee17 ...found WIM file boot.wim ...found file "\Windows\Boot\PXE\bootmgr.exe" Using bootmgr.exe via 0x2bc18 len 0x7fd80 ...extracted bootmgr.exe Emulating drive 0x81 Entering bootmgr.exe with parameters at 0x2a520
As for bootmgr.exe, it will try to read the essential BCD from \Boot\BCD. Once it succeeds, it will inspect the BCD and act accordingly. Ensure that the BCD contains valid data and refers to files and paths that are reachable within the wimboot virtual filesystem.
Ensure that the BCD file contains valid configuration. To do this, you need to examine it with the Windows-only bcdedit.exe program. Alternatively, the hivex registry hive libraries and associated language bindings can be used on other platforms, but the BCD hive structure and data encoding makes it very cumbersome.
Here's an example, using bcdedit.exe to dump the BCD contents:
> bcdedit /enum all /store test.bcd
Windows Boot Manager
--------------------
identifier {bootmgr}
description Windows 7 Boot Manager
displayorder {9b0a74...}
timeout 30
Windows Boot Loader
-------------------
identifier {9b0a74...}
device ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
description Windows 7 Installation
osdevice ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
systemroot \Windows
detecthal Yes
winpe Yes
Setup Ramdisk Options
---------------------
identifier {ramdiskoptions}
description Ramdisk Options
ramdisksdidevice boot
ramdisksdipath \Boot\boot.sdi
You might find that the BCD file contains references to files that have paths that will not ever match wimboot's search list (\, \Boot, \Sources, etc). If this is the case, you may want to either edit or recreate the BCD file.
Here's an example of creating a BCD file from scratch:
set BCDSTORE=BCD
bcdedit /createstore %BCDSTORE%
bcdedit /store %BCDSTORE% /create {ramdiskoptions} /d "Ramdisk Options"
bcdedit /store %BCDSTORE% /set {ramdiskoptions} ramdisksdidevice Boot
bcdedit /store %BCDSTORE% /set {ramdiskoptions} ramdisksdipath \Boot\boot.sdi
for /f "Tokens=3" %%x in ('bcdedit /store %BCDSTORE% /create /d "Windows 7 Installation" /application osloader') do set GUID=%%x
bcdedit /store %BCDSTORE% /set %GUID% systemroot \Windows
bcdedit /store %BCDSTORE% /set %GUID% detecthal Yes
bcdedit /store %BCDSTORE% /set %GUID% winpe Yes
bcdedit /store %BCDSTORE% /set %GUID% osdevice ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
bcdedit /store %BCDSTORE% /set %GUID% device ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
bcdedit /store %BCDSTORE% /create {bootmgr} /d "Windows 7 Boot Manager"
bcdedit /store %BCDSTORE% /set {bootmgr} timeout 30
bcdedit /store %BCDSTORE% /set {bootmgr} displayorder %GUID%
bcdedit /enum all /store %BCDSTORE%
The BCD is a complex beast with lots of options, which makes it hard to know which details are required for the specific type of boot (ADK, AIK, WDS, etc). Refer to the iPXE WinPE documentation for more details.
WIM files can be opened using a variety of tools. Should you need to verify the contents of the WIM image without access to Windows, use the example application applywim supplied with wimlib. This can be useful for verifying that bootmgr.exe is indeed located in the \Windows\Boot\PXE\ directory.