Creating a bootable UEFI DUET USB stick

Now that one of my patches has made it into the UEFI/EDK2 SVN repository, I'm going to provide a quite guide on the easiest way to create a bootable UEFI USB stick for legacy platforms, on Windows.
In case you are not familiar with EFI/UEFI, it is very much possible to run EFI even on legacy (i.e. non EFI) hardware, through a process called DUET, which provides a complete EFI emulation layer using the underlying BIOS. This is great for testing, without having to modify your hardware in any way.

It is all provided by the DuetPkg of the EDK2. However, the main issue with EDK2 is that it may be a difficult to get working, unless you used the same development tools as the EDK2 developers, which, on Windows would default to Visual Studio 2008, which is not free.

Isn't there simple way to use freely available tools on Windows, to easily compile a DUET USB bootstick?
Glad you asked. There is now, and here is the complete process that goes with it:
  • Download and install the Windows Server 2003 WinDDK, v3790.1830, using this direct link (230 MB ISO download). This is of course not the latest DDK but unless you want to waste time in extra configuration, you might as well go with the supported version. If I find the time to fix EDK2 for the latest, I may send another patch to the EDK2 team, but for now, this will have to do.
  • (Optional) If you plan to use ASL to compile ACPI, which isn't needed for DUET, create a C:\ASL directory, download the Microsoft ASL Assembler/Compiler archive from here, open the .exe with 7-zip. Then open the .msi from the .exe (Open Inside), find the file _C6C6461BF87C49D66033009609D53FA5, extract it to your C:\ASL directory and rename it asl.exe (count on Microsoft to provide an installer... for a mere 55 KB exe). Also note that the ASL compiler is for 32 bit only. If you're running 64 bit, tough luck.
  • Mount or burn the ISO and install the WinDDK, to the default C:\WINDDK\3790.1830 directory.
  • If needed, download and install TortoiseSVN, or any other SVN client.
  • Fetch the latest EDK2 from SVN, using https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2 as the SVN repository.
  • Open a DDK console ("Development Kits" → "Win2k3 Free x64 Build Environment" or "Win2k3 Free x86 Build Environment") and navigate to your edk2 direcvtory
  • Run the command:
    This will initialize your environment by creating the required files in the Conf\ directory. You can safely ignore the warning about cygwin.
  • Open the file Conf\target.txt and edit the TOOL_CHAIN_TAG line to have:
    You also may want to change MAX_CONCURRENT_THREAD_NUMBER and make sure TARGET_ARCH is properly set to either IA32 or X64 according to your needs, as it avoids having to provide extra arch parameter when invoking the commands below).
  • In the console, run (32 bit):
    build -p DuetPkg\DuetPkgIA32.dsc
    or (64 bit)
    build -p DuetPkg\DuetPkgX64.dsc
    It may take a while but it should complete successfully.
  • cd to DuetPkg\ and run:
  • Plug in your USB key and check its drive letter. In the following I will assume it is F:, and run:
    CreateBootDisk.bat usb F: FAT16
  • Unplug and replug the key as requested, and run:
    CreateBootDisk.bat usb F: FAT16 step2
You should now have a bootable UEFI USB key. Plug that into a PC, boot it, and you will be welcomed into the wonderful world of EFI.
Note that if you rebuild any of the packages, you only have to perform the last step to update the key.


  1. Pete,

    I think the edksetup.bat worked fine. I got a message that said, "Rebuilding of tools is not required...." But it created the \Conf\target.txt file. I changed the TOOL_CHAIN_TAG like you mentioned.


    The build executable isn't in the root path like you make it seem. It was in the BaseTools\Bin\Win32 folder. So I ran it and called the switches you mentioned.

    But I got the following error:

    error 5000: Environment variable not found WORKSPACE

  2. The build executable comes from the DDK, and should be available without having to specify a path if you opened a DDK console. If you cannot invoke "build" from the commandline, then either you haven't opened a DDK prompt (which is different from a regular console Windows) or your DDK environment isn't setup properly.
    I guess the error you get is the logical consequence of the above.
    Please make sure you open a DDK prompt before invoking the other commands.

    1. Petes,

      Thanks for replying. I think something was wrong with my Win DDK installation. I couldn't locate the DDK console. So I used a normal console and CDed to the build.exe app.

      I'm downloading the DDK again and I'll see what happens.


    2. Pete,

      Could you maybe tell me the exact location of where the WINDDK console is supposed to be? The folder names you list above don't exist on a fresh install. And Googling for WINDDK console brings up very little relevant results.


  3. When I boot from USB key after completing all steps, system hangs in "MBR start !" message and nothing happens after that. Please help me in this.

    1. Having a Duet boot disk does not mean that it's going to work with all hardware. Last time I tried, I remember that one of the PCs I had wouldn't boot from it at all (and I think I had the "MBR start !" error then), which I suspect is due to an issue with the EDK2.

      I'm afraid you'll have to dig into EDK development to figure out why your system doesn't boot.

  4. in the last "stage" when writing CreateBootDisk usb F: FAT16 there is an error. failed to read =and write DRB and MBR . i dont know whats does this mean.

  5. Hey Pete,

    Love your blogs. I got a prebuilt Duet package that I installed to usb key and Im trying to get rid of the delay at the shell where youve got 5 seconds to escape out of running startup.nsh. Normally i would set the nvram variable to pass the delay but its an old machine. So I downloaded the EDK2 source and manually set the delay from 5 to 0 and compiled it with VS2013. At first the usb key refused to load my shell.efi but after recompiling under the x64 build option it would work until i renamed my shell.efi to bootx64.efi. There it would load at boot but crash after map-r displayed all the drives. Was wondering if you have any suggestions? Thanks.