In my last article, I discussed an old, but still active, mechanism for Windows and BIOS to communicate with each other regarding boot configuration:  the Simple Boot Flag.

There is, however, another, more modern and industry-standard mechanism for OS to BIOS boot configuration communication, and that is the subject of this article:  the OsIndicationsOsIndicationsSupported variable pair.

Summary

This mechanism is defined in the UEFI Specification.  BIOS and the OS exchange boot configuration parameters through these two UINT64 variables:  OsIndications and OsIndicationsSupported.  The UEFI Specification considers these two variables to have an architecturally-defined meaning, and so are defined in the §3.3 Globally Defined Variables section of the specification, part of the EFI_GLOBAL_VARIABLE namespace.


The variable attributes (middle column) denote that these variables are available both in the pre-boot/boot services (BS) and run-time (RT) phases.  Furthermore, OsIndications is non-volatile (NV) so it persists across power-off cycles.

Details

The central location for documentation on OsIndications is §8.5.4 of the UEFI Specification.
  • The OsIndications variable returns a UINT64 bitmask owned by the OS and is used to indicate which features the OS wants firmware to enable or which actions the OS wants the firmware to take.
  • The OsIndicationsSupported variable returns a UINT64 bitmask owned by the firmware and indicates which of the OS indication features and actions that the firmware supports. This variable is recreated by firmware every boot, and cannot be modified by the OS.
In the EDK2 reference implementation, these variables are defined in GlobalVariable.h:
edk2\MdePkg\Include\Guid\GlobalVariable.h
///
/// Allows the firmware to indicate supported features and actions to the OS.
/// Its attribute is BS+RT.
///
#define EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME    L"OsIndicationsSupported"
///
/// Allows the OS to request the firmware to enable certain features and to take certain actions.
/// Its attribute is NV+BS+RT.
///
#define EFI_OS_INDICATIONS_VARIABLE_NAME            L"OsIndications"

What are the "actions" that the OS might want BIOS to take?  These are best described by listing the #defines from the EDK2.  Both of the variables are bitfields and share a common definition, defined in UefiSpec.h:

edk2\MdePkg\Include\Uefi\UefiSpec.h
//
// Firmware should stop at a firmware user interface on next boot
//
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI                    0x0000000000000001
#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION             0x0000000000000002
#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED  0x0000000000000004
#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED            0x0000000000000008
#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED     0x0000000000000010
#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY          0x0000000000000040
#define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH         0x0000000000000080

I won't waste space by cutting and pasting the entire §8.5.4 from the specification, but here's an example of how the EFI_OS_INDICATIONS_BOOT_TO_FW_UI bit is defined:
The EFI_OS_INDICATIONS_BOOT_TO_FW_UI bit can be set in the OsIndicationsSupported variable by the firmware, if the firmware supports OS requests to stop at a firmware user interface. The EFI_OS_INDICATIONS_BOOT_TO_FW_UI bit can be set by the OS in the OsIndications variable, if the OS desires for the firmware to stop at a firmware user interface on the next boot. Once the firmware consumes this bit in the OsIndications variable and stops at the firmware user interface, the firmware should clear the bit from the OsIndications variable in order to acknowledge to the OS that the information was consumed and, more importantly, to prevent the firmware user interface from showing again on subsequent boots.
For definition of the rest of the bits, please see §8.5.4 in the UEFI Specification.

Example

Here is a quick example of how the EDK2 uses OsIndications in practice, specifically, how the UEFI Shell function ShellCommandRunReset() supports the "-fwui" parameter so the user can request that the next boot enter the BIOS setup.

edk2\ShellPkg\Library\UefiShellLevel2CommandsLib\Reset.c
...
if (ShellCommandLineGetFlag (Package, L"-fwui")) {

    DataSize  = sizeof (OsIndications);
    Status = gRT->GetVariable (
                    EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, &gEfiGlobalVariableGuid,
                    &Attr, &DataSize, &OsIndications
                    );
    if (!EFI_ERROR (Status)) {
      if ((OsIndications & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0) {
        DataSize = sizeof (OsIndications);
        Status = gRT->GetVariable (
                        EFI_OS_INDICATIONS_VARIABLE_NAME, &gEfiGlobalVariableGuid,
                        &Attr, &DataSize, &OsIndications
                        );
        if (!EFI_ERROR (Status)) {
          OsIndications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
        } else {
          OsIndications = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
        }
        Status = gRT->SetVariable (
                        EFI_OS_INDICATIONS_VARIABLE_NAME, &gEfiGlobalVariableGuid,
                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                        sizeof (OsIndications), &OsIndications
                        );
      }
    }
    if (EFI_ERROR (Status)) {
      ShellStatus = SHELL_UNSUPPORTED;
      goto Error;
    }
  }
What the code is doing is:
  1. check to see if user passed the "-fwui" parameter
  2. get OsIndicationsSupport variable
  3. if EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set (i.e., BIOS supports the Setup feature), then get OsIndications
  4. set the EFI_OS_INDICATIONS_BOOT_TO_FW_UI bit in OsIndications
Now, the next boot will be to the BIOS Setup UI.

Conclusion

Note that unlike the Simple Boot Flag, OsIndications is industry-standard, supported by both Windows and Linux.  Moreover, it is not x86-specific, but is supported by ARM's EBBR specification.  See more about the EBBR in ARM's SystemReady Specifications.  For example:


I hope this article has brought to light the workings of the OsIndications—OsIndicationsSupported variable pair, and helps you leverage this technique in your work.

Post a Comment

Be sure to select an account profile (e.g. Google, OpenID, etc.) before typing your comment!