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 OsIndications—OsIndicationsSupported 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"
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:
- check to see if user passed the "-fwui" parameter
- get OsIndicationsSupport variable
- if EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set (i.e., BIOS supports the Setup feature), then get OsIndications
- 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:
Post a Comment
Be sure to select an account profile (e.g. Google, OpenID, etc.) before typing your comment!