Differences

This shows you the differences between two versions of the page.

appnote:wimboot_architecture [2015/01/02 14:07] (current)
svenx Article created.
Line 1: Line 1:
 +====== wimboot architecture ======
 +''[[: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.
 +===== How wimboot works =====
 +
 +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).
 +
 +==== Command line processing ====
 +
 +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.
 +
 +==== CPIO archive extraction ====
 +
 +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 ''[[:cmd: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 ''[[:cmd: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 wimboot virtual filesystem ====
 +
 +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 ''[[:cmd: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.
 +
 +==== Extracting bootmgr.exe ====
 +
 +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.
 +
 +==== Running bootmgr.exe ====
 +
 +At the final stage of ''wimboot'' execution, it reads ''bootmgr.exe'' into memory and hands over execution to it.
 +
 +==== EFI platform differences ====
 +
 +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''.
 +
 +===== How bootmgr.exe works =====
 +
 +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 //[[http://technet.microsoft.com/en-us/library/cc771845|How Booting into a Boot Image Works]]// documentation for some additional details.
 +
 +==== Reading the BCD file ====
 +
 +''bootmgr.exe'' first interacts with the virtual filesystem by trying
 +to read the BCD ([[http://technet.microsoft.com/en-us/library/cc770770|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 //[[http://technet.microsoft.com/en-us/library/ee221031|Boot Process and BCDEdit]]// documentation for some additional details.
 +
 +==== Reading additional files ====
 +
 +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 [[http://technet.microsoft.com/en-us/library/cc732289|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.
 +
 +==== Mounting the ramdisk ====
 +
 +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.
 +
 +==== Executing winload.exe ====
 +
 +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''.
 +
 +===== Troubleshooting =====
 +
 +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.
 +
 +==== Example errors ====
 +
 +Some common error messages are listed below:
 +
 +  * When ''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.
 +
 +  * When ''bootmgr.exe'' cannot find or read the SDI file:
 +
 +    Status: 0xc000000f
 +    Info: The boot selection failed because a required device is inaccessible.
 +
 +  * When ''bootmgr.exe'' cannot find or read the WIM image:
 +
 +    Status: 0xc000000f
 +    Info: A required device isn't connected or can't be accessed.
 +
 +==== Finding the culprit ====
 +
 +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:
 +
 +  * referring to the wrong file name; or
 +  * referring to files outside the directories provided by the ''wimboot'' virtual file systems, such as ''\'', ''\Boot'', ''\Sources'', etc.
 +
 +By following the ''wimboot''/''bootmgr.exe'' execution chain, troubleshooting is made a bit easier:
 +  - Make sure to use the latest ''wimboot'' version.
 +  - Ensure that the ''[[:cmd:imgfetch]]'' commands are successful.
 +    * Use the ''[[:cmd:imgstat]]'' command (optionally followed by ''[[:cmd:prompt]]'' in scripts) to verify that the files fetched by ''[[:cmd:imgfetch]]'' were successfully retrieved.
 +  - Use the ''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 ''[[:cmd: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.
 +
 +==== BCD contents ====
 +
 +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 [[http://libguestfs.org/hivex.3.html|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 [[:howto:winpe|WinPE]] documentation for more details.
 +
 +==== WIM image contents ====
 +
 +WIM files can be opened using a [[http://en.wikipedia.org/wiki/Windows_Imaging_Format#Tools|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 [[http://wimlib.sourceforge.net/|wimlib]]. This can be useful for verifying that ''bootmgr.exe'' is indeed located in the ''\Windows\Boot\PXE\'' directory.
 
appnote/wimboot_architecture.txt · Last modified: 2015/01/02 14:07 by svenx
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
All uses of this content must include an attribution to the iPXE project and the URL http://ipxe.org
References to "iPXE" may not be altered or removed.