Image of Modern Operating Systems (3rd Edition)
Image of Advanced Programming in the UNIX Environment, Second Edition (Addison-Wesley Professional Computing Series)
Image of Android Wireless Application Development
Image of XSLT 2.0 and XPath 2.0 Programmer's Reference (Programmer to Programmer)

Using UEFI DUET to boot Fedora 12

You may have noticed that recent versions of Fedora support UEFI (Unified Extensive Firmware Interface) booting. With the release of Fedora 12, UEFI booting is now stable enough to consider switching to if your hardware platform supports it.

UEFI is a standards based environment that specifies the layer between an operating system and the platform firmware for running pre-boot applications and for booting an operating system. UEFI is a follow on to original EFI specification developed by Intel in the last 1990s. Until recently, UEFI was restricted to high-end servers but is now becoming more commonplace on commodity servers and desktops due to the growing need to support disk volumes greater that 2 TiB.

The legacy MBR (Master Boot Record) partition table can only describe partitions up to 32-bit LBAs, each LBA describing a 512-byte sector, for a total of 41 bits of addressability, or 2 TiB ≈ 2.2 TB. To support partitions greater than 2 TiB, UEFI uses a GPT (GUID Partition Table). The 2 TiB limit is a result of the layout of the MBR; it is not a BIOS limit.

Not many Fedora users have UEFI enabled platforms and thus think that they cannot experminent with UEFI booting. This is not true. In the early days of the IA64 development effort, circa 1998, Intel developed DUET (Developer’s UEFI Emulation, originally called UoL) to provide an EFI IA64 development environment on existing hardware to aid in the initial development and debug of native EFI drivers. Since then, as part of the EDK (EFI Developers Kit), DUET has been extended to support IA32 and X64 architectures. In a nutshell, DUET provides a UEFI environment on a non-UEFI platform. This is achieved by creating an UEFI file image for a bootable device, and then ‘booting” that image as a legacy boot. This is not a product solution for UEFI, but it does make a good test bed for users and developers who want to test their UEFI drivers and applications on real hardware.

So how do you get hold of DUET? Generally you have to download the EDK from the Tianocore website and build it to get DUET. I suggest you download the latest release snapshot rather than a nightly build. According to the build instructions which come with the EDK (See the EDK Getting Started Guide), you must must build the EDK on a Microsoft Windows 2000 or Microsoft Windows XP operating system platform using Microsoft Visual Studio .NET 2003 Enterprise. However in this blog I will show you how to build a 32-bit UEFI version of DUET via the command line using Visual Studio 10 and MASM 6.15 on Microsoft Vista.

Why do you need MASM 6.15 and where do you get it from? You need this particular version of MASM – which was released circa 1994 – because it has support for the linker /TINY switch. This switch enables the tiny model and is used to produce a .com file (prior to MASM 6.0 the EXE2BIN utility was used to generate a .com file.) If you do a Web search you will find plenty of sites to download MASM 6.15 from. Just make sure that the download also contains the linker that supports the /TINY switch. You should install MASM in C:\MASM615 as that is the default expected location.


There are a number of different files types in the build tree which you should be aware of. A .ENV file describes and setups the build environment. A .DSC file is a build description text file, which defines the components, build rules and commands, FV definitions, and package file definitions for a build tip. As discussed previously, a file with a .COM extension is an executable file that is produced by Microsoft LINK using the /TINY switch. A file with a .EXE extension is an executable file that is produced by Microsoft LIB and Microsoft LINK. A file with an .EFI extension is an intermediate code file that is produced by the FWIMAGE build tool.

Assume for the remainder of this post that the EDK is installed at C:\TianoCore\Edk and that we want to build a 32-bit UEFI version of DUET. Before you can build DUET you need to modify C:\Tianocore\Edk\Sample\CommonTools.env to specify the paths to the compiler, assembler, and linker as shown below.

# Build tools
CC                = cl
LINK              = link
LIB               = lib
# When using VS ml to compile 16bit code, please add /omf compiler option 
ASM               = ml

ASM16             = C:\masm615\ml
ASMLINK16         = C:\masm615\link
ASMLINK           = C:\masm615\link
ASM16             = $(EDK_TOOLS_BIN)\Ia32\$(EFI_ASSEMBLER_NAME)\bin\ml
ASMLINK16         = $(EDK_TOOLS_BIN)\Ia32\$(EFI_ASSEMBLER_NAME)\binr\link
ASMLINK           = $(EDK_TOOLS_BIN)\Ia32\$(EFI_ASSEMBLER_NAME)\binr\link

You also need to set EDK_SOURCE to C:\TianoCore\Edk.

The actual DUET build is kicked off from the $EDK_SOURCE\Sample\Platform\DUET subdirectory by invoking nmake uefi32 in a Visual Studio command prompt window. You could use a regular command prompt window and set up you path to include the cl compiler and the other utilities but Visual Studio does this work for you when you invoke a Visual Studio command prompt window.

The build creates a $EDK_SOURCE\Sample\Platform\DUET\uefi32 subdirectory (what the EDK calls a build tip)and places the output from the build into that directory and a number of subdirectories under it. If you want to cleanup the build enviroment, you can do so by invoking nmake uefi32clean. If you want view the build logs for the various components they are located at ..\DUET\uefi32\logs

The TianoCore EDK does not build the EFI shell and applications but incorporates pre-build images. See the subdirectories under$EDK_SOURCE\Other\Maintained\Shell. If you want to rebuild the shell and other applications for your particular platform, you need to download an additional package from the TianoCore EFI Shell Project and modify a couple of .DSC files in source code tree to enable these compoments to be built.

After you have build the target you want, the next thing is to build a DUET bootable USB disk (key). For example, suppose we wish to create a 32-bit UEFI DUET bootable USB disk. In your Microsoft Vista Visual Studio 10 command prompt window, change your current directory to $EDK_SOURCE\Sample\Platform\DUET\uefi32 and execute the following steps

  • Format a FAT32 USB disk.
  • Set the EFI_BOOT_DISK environmental variable to the drive ID of the USB disk, e.g. set EFI_BOOT_DISK=F:
  • Execute nmake createusb32
  • Remove the USB disk when quesescant and reinsert
  • Execute nmake usb32

To format a bootable USB key I recommend that you use a tool such as HP’s USB Disk Storage Format Tool which can be downloaded from many Web sites. This tool can be run either as a GUI application or as a command line applcation. Here is a screen capture of the entire process:


Note that you should remove the USB key when prompted and install it again after a few seconds. Make sure that all activity on the USB key has stopped before removing it otherwise you will end up with a corrupted USB key. The bootable USB key is now ready for use.

Here is a Flash video of Fedora 12 being booted using the UEFI USB key.

I apologize for the shaky video. I held the camera in my right hand while working the keyboard with my left hand. At the Intel splash screen I pressed F10 to go into the Boot Options Menu. There I selected the USB KEY (named Patriot) and was booted into DUET. DUET has a number of options and screens. I choice to manually execute an EFI application, i.e. GRUB.EFI which resides in the subdirectory /efi/redhat on a FAT partition on my first hard disk.

I could have just as easily invoked any one of a number of EFI applications prior to selecting GRUB.EFI to boot into Fedora 12 as DUET contains a full EFI shell not just a minimum shell. I could also have configured DUET to directly invoke GRUB.EFI without first dropping into the EFI shell. By the way, observant viewers of the video may have noticed that the particular hardware (an Intel DX48BT2) used in the video supports UEFI (it shows as the option “Internal EFI Shell” in the Boot Options Menu) and thus I did not need to perform a UEFI boot using the USB key. If you are unfamilar with the EFI shell, Intel has a good online tutorial that is worth doing.

I last worked on EFI-based systems in the early 2000s as part of an IA64 development program. Unfortunately, while the specifications have stabilised and matured, the EFI/UEFI code base does not appear to have changed that much with little new real functionality evident. That might change with the emergence of more UEFI-based systems. Apple’s popular Intel-based systems are all EFI-based even if their implementation according to all reports is not strictly EFI or UEFI-comforming. This has lead to the emergence of a large cadre of experimenters and various projects such as rEFIt whose goal is to support the easy booting multiple operating systems and access to the pre-boot environment. If your are in the market for a new motherboard, I recommend that you now add UEFI to your “must have” feature list.

As always, I encourage you to experiment with UEFI booting for yourself.

3 comments to Using UEFI DUET to boot Fedora 12

  • Billy

    First, I would like to say, pretty good overall, but a good amount of miss information as well. The limit of the 2tb booting is not the BIOS, it’s the MBR table. There is no reason a normal BIOS machine with a GPT installed couldn’t boot from a partition > 2TB. Since GPT requires the legacy MBR still be present, there is no reason the code stored in the MBR couldn’t boot from any location, in any partition (no matter the size) stored in the GPT. It’s just companies want you to believe that it’s impossible and you must upgrade. I have written my fair share of software (including my own MBR, multiple boot loaders, and small operating systems) and can confirm that you can access > 2tb using bios functions, so the only limitation is purely implementation of the software. Not only is booting from GPT without EFI possible, it’s actually fairly easy.

    • > The limit of the 2tb booting is not the BIOS, it’s the MBR table.

      Correct. I have removed the sentence that implied a BIOS limit. Thank you for spotting the error.

      > There is no reason a normal BIOS machine with a GPT installed couldn’t boot from a partition > 2TB.

      I agree.

      > Since GPT requires the legacy MBR still be present

      Huh? Where did that requirement come from? You can have a GPT without having an MBR present. In fact you can embed a BIOS boot partition inside GPT if you want to. The T13 (ATA) GPT partition record design now includes a Legacy BIOS Bootable bit that can be set for a partition like a BIOS boot partition. The algorithm is documented in T13 EDD-4 revision 2 and later. But again there is no requirement for an MBR to be present.

      > Not only is booting from GPT without EFI possible, it’s actually fairly easy.

      Correct. Just look at GRUB2.

  • Decent reading. Like your site design as well. Keep up your good work.