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.