From a26a5f16399cf57dab956cab1c1be0943c2ccbd1 Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Sat, 3 Oct 2026 19:21:28 -0700 Subject: [PATCH] feat(eficore): advertise the sort key and preferred entry features --- crates/eficore/src/bootloader_interface.rs | 22 ++++++++++++++++--- .../src/bootloader_interface/bitflags.rs | 6 +++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/crates/eficore/src/bootloader_interface.rs b/crates/eficore/src/bootloader_interface.rs index 3b008b3..c776105 100644 --- a/crates/eficore/src/bootloader_interface.rs +++ b/crates/eficore/src/bootloader_interface.rs @@ -13,8 +13,8 @@ use uefi_raw::table::runtime::VariableVendor; /// bitflags: LoaderFeatures bitflags. mod bitflags; -/// The name of the bootloader to tell the system. -const LOADER_NAME: &str = "Sprout"; +/// The name and version of the bootloader to tell the system. +const LOADER_NAME: &str = concat!("Sprout ", env!("CARGO_PKG_VERSION")); /// Represents the configured timeout for the bootloader interface. #[derive(Default)] @@ -56,7 +56,6 @@ impl BootloaderInterface { /// The feature we support in Sprout. fn features() -> LoaderFeatures { LoaderFeatures::Xbootldr - | LoaderFeatures::LoadDriver | LoaderFeatures::Tpm2ActivePcrBanks | LoaderFeatures::RetainShim | LoaderFeatures::ConfigTimeout @@ -66,6 +65,8 @@ impl BootloaderInterface { | LoaderFeatures::EntryOneShot | LoaderFeatures::BootCounting | LoaderFeatures::SavedEntry + | LoaderFeatures::EntryPreferred + | LoaderFeatures::SortKey } /// Tell the system that Sprout was initialized at the current time. @@ -347,6 +348,21 @@ impl BootloaderInterface { .filter(|value| !value.is_empty())) } + /// Get the preferred entry set by the bootloader interface. + /// Unlike the default entry, an entry with no boot counter tries left is not used. + pub fn get_preferred_entry() -> Result> { + // An empty value is treated as if the preferred entry was not set. + Ok(Self::VENDOR + .get_cstr16("LoaderEntryPreferred") + .context("unable to get preferred entry from bootloader interface")? + .filter(|value| !value.is_empty())) + } + + /// Remove the entry that was saved by a previous boot. + pub fn remove_last_booted_entry() -> Result<()> { + Self::VENDOR.remove("LoaderEntryLastBooted") + } + /// Get the oneshot entry set by the bootloader interface. /// This should be the entry we boot. pub fn get_oneshot_entry() -> Result> { diff --git a/crates/eficore/src/bootloader_interface/bitflags.rs b/crates/eficore/src/bootloader_interface/bitflags.rs index 280ae0a..aa146e5 100644 --- a/crates/eficore/src/bootloader_interface/bitflags.rs +++ b/crates/eficore/src/bootloader_interface/bitflags.rs @@ -42,5 +42,11 @@ bitflags! { const Type1UkiUrl = 1 << 17; /// Bootloader indicates TPM2 active PCR banks. const Tpm2ActivePcrBanks = 1 << 18; + /// Bootloader supports LoaderEntryPreferred. + const EntryPreferred = 1 << 19; + /// Bootloader supports the keyboard layout. + const KeyboardLayout = 1 << 20; + /// Bootloader measures SMBIOS data. + const SmbiosMeasured = 1 << 21; } }