Friday, May 30, 2014

Exploring Windows UEFI - Part 1.

Newer versions of Windows 8/8.1 are installed on computers with UEFI firmware.

The combination UEFI/GPT is not so well known as BIOS/MBR. In a series of posts I will try to explain practical aspects of Windows on UEFI/GPT. The first post in the series is about exploring some UEFI variables and the functionality it offers to users.

From Windows 8/7 you can access UEFI firmware variables in two ways:
  a) using Get/SetFirmwareEnvironmentVariable functions or
  b) using BCD (Boot Configuration Data) interface (either with bcdedit or WMI BCD Provider)

On UEFI boot entry variables are named "BootNNNN" where NNNN are hexadecimal numbers:
     for example - Boot0000, Boot0002, Boot0003, Boot2001, ....
     boot entry numbers must not be consecutive.

There is a "main" NVRAM variable which holds a list of boot entry numbers - "BootOrder" and defines the boot priority of boot entries, the first number in the list is the first boot entry candidate (if BootNext is not defined).
Let us mention also "BootCurrent" NVRAM variable which (if defined) holds the number of current boot entry used for booting the OS - Windows, Linux etc.

Linux distributions include the utility "efibootmgr" which gives access to UEFI(NVRAM) variables and keep a copy of NVRAM in "/sys/firmware/efi/vars" directory.
Windows 8/7 delivers bcdedit command line utility which allow some access to UEFI NVRAM variables, mainly read access, but you can also change the value of some variables.

Let us mention also the "Timeout" variable to end the list of all "basic" NVRAM UEFI variables. "Timeout" defines the timeout in seconds. Windows installations set Timeout to 2 by default.

So we have mentioned so far:
 - BootOrder - list of NNNN
 - BootNNNN - boot entries
 - BootCurrent - NNNN of current boot entry
 - BootNext - NNNN of boot entry to be used on next boot
 - Timeout

In Windows BCD there are equivalents for the above notions:
  BootOrder => DisplayOrder element of {fwbootmgr}
  BootNNNN => objects with special type of "0x101FFFFF"
  BootCurrent => not mapped, but we have {current} object for Windows loaders
  BootNext => BootSequence of {fwbootmgr}
  Timeout => Timeout of {fwbootmgr}

Experimenting with BootOrder (DisplayOrder element of {fwbootmgr}) from Windows I did not succeed to change NVRAM variable permanently. You can change the order temporarily but on reboot edits are lost. So only direct changing of BootOrder using SetFirmwareEnvironmentVariable function should give a permanent change.

It should be mentioned that Windows keeps a copy of System-BCD in registry:
where it stores a mix of Windows and NVRAM boot related variables.

Experimenting to change some of the elements of BootNNNN - firmware objects in BCD - had also either temporary or no effect.
A boot entry from NVRAM is mapped in Windows BCD as an object with a special type of 0x101FFFFF (firmware application) with three elements: "ApplicationDevice", "ApplicationPath" and "Description".

Creation of new UEFI NVRAM boot entries has also failed for Windows (Microsoft) related paths (for "bootgmr.efi" and "bootmgfw.efi") but you can create a boot entry for a "foreign" operating system like Ubuntu or Fedora using real paths (existing UEFI applications on EFI System Partition) - for example "Z:\EFI\ubuntu\grubx64.efi", where Z: is mapped to ESP (EFI System Partition on GPT disk) using "mountvol.exe".

Timeout can be changed permanently using bcdedit or WMI interface.

BootNext can be changed permanently (its live is until next reboot) and I have used this functionality in the tool "BootNext - v1.0" to allow Windows 8/7 users to boot directly to any installed device or OS (Windows 7/8, Ubuntu, Fedora).
The utility also offers simple one click creation of safe mode loaders (and direct boot to safe mode) as new Windows 8 modern boot menu has some obscure way of accessing the safe mode boot option.

Here is the main form of "BootNext" utility:

BootNext tool

In Part 2 I will examine an easy way of exploring ESP - EFI System Partition from Windows 7/8.