Skip to content

Commit f9dd56c

Browse files
committed
feat(bootloader-interface): add support for LoaderFeatures
1 parent 4129ae4 commit f9dd56c

File tree

5 files changed

+82
-6
lines changed

5 files changed

+82
-6
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ edition = "2024"
99

1010
[dependencies]
1111
anyhow = "1.0.100"
12+
bitflags = "2.10.0"
1213
toml = "0.9.8"
1314
log = "0.4.28"
1415

src/integrations/bootloader_interface.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::integrations::bootloader_interface::bitflags::LoaderFeatures;
12
use crate::platform::timer::PlatformTimer;
23
use crate::utils::device_path_subpath;
34
use crate::utils::variables::{VariableClass, VariableController};
@@ -6,6 +7,9 @@ use uefi::proto::device_path::DevicePath;
67
use uefi::{Guid, guid};
78
use uefi_raw::table::runtime::VariableVendor;
89

10+
/// bitflags: LoaderFeatures bitflags.
11+
mod bitflags;
12+
913
/// The name of the bootloader to tell the system.
1014
const LOADER_NAME: &str = "Sprout";
1115

@@ -18,6 +22,11 @@ impl BootloaderInterface {
1822
"4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
1923
)));
2024

25+
/// The feature we support in Sprout.
26+
fn features() -> LoaderFeatures {
27+
LoaderFeatures::LoadDriver | LoaderFeatures::Tpm2ActivePcrBanks | LoaderFeatures::RetainShim
28+
}
29+
2130
/// Tell the system that Sprout was initialized at the current time.
2231
pub fn mark_init(timer: &PlatformTimer) -> Result<()> {
2332
Self::mark_time("LoaderTimeInitUSec", timer)
@@ -45,13 +54,26 @@ impl BootloaderInterface {
4554
)
4655
}
4756

48-
/// Tell the system what loader is being used.
57+
/// Tell the system what loader is being used and our features.
4958
pub fn set_loader_info() -> Result<()> {
50-
Self::VENDOR.set_cstr16(
51-
"LoaderInfo",
52-
LOADER_NAME,
53-
VariableClass::BootAndRuntimeTemporary,
54-
)
59+
// Set the LoaderInfo variable with the name of the loader.
60+
Self::VENDOR
61+
.set_cstr16(
62+
"LoaderInfo",
63+
LOADER_NAME,
64+
VariableClass::BootAndRuntimeTemporary,
65+
)
66+
.context("unable to set loader info variable")?;
67+
68+
// Set the LoaderFeatures variable with the features we support.
69+
Self::VENDOR
70+
.set_u64le(
71+
"LoaderFeatures",
72+
Self::features().bits(),
73+
VariableClass::BootAndRuntimeTemporary,
74+
)
75+
.context("unable to set loader features variable")?;
76+
Ok(())
5577
}
5678

5779
/// Tell the system the relative path to the partition root of the current bootloader.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use bitflags::bitflags;
2+
3+
bitflags! {
4+
/// Feature bitflags for the bootloader interface.
5+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6+
pub struct LoaderFeatures: u64 {
7+
/// Bootloader supports LoaderConfigTimeout.
8+
const ConfigTimeout = 1 << 0;
9+
/// Bootloader supports LoaderConfigTimeoutOneShot.
10+
const ConfigTimeoutOneShot = 1 << 1;
11+
/// Bootloader supports LoaderEntryDefault.
12+
const EntryDefault = 1 << 2;
13+
/// Bootloader supports LoaderEntryOneShot.
14+
const EntryOneShot = 1 << 3;
15+
/// Bootloader supports boot counting.
16+
const BootCounting = 1 << 4;
17+
/// Bootloader supports detection from XBOOTLDR partitions.
18+
const Xbootldr = 1 << 5;
19+
/// Bootloader supports handling of random seeds.
20+
const RandomSeed = 1 << 6;
21+
/// Bootloader supports loading drivers.
22+
const LoadDriver = 1 << 7;
23+
/// Bootloader supports sort keys.
24+
const SortKey = 1 << 8;
25+
/// Bootloader supports saved entries.
26+
const SavedEntry = 1 << 9;
27+
/// Bootloader supports device trees.
28+
const DeviceTree = 1 << 10;
29+
/// Bootloader supports secure boot enroll.
30+
const SecureBootEnroll = 1 << 11;
31+
/// Bootloader retains the shim.
32+
const RetainShim = 1 << 12;
33+
/// Bootloader supports disabling the menu via menu timeout variable.
34+
const MenuDisable = 1 << 13;
35+
/// Bootloader supports multi-profile UKI.
36+
const MultiProfileUki = 1 << 14;
37+
/// Bootloader reports URLs.
38+
const ReportUrl = 1 << 15;
39+
/// Bootloader supports type-1 UKIs.
40+
const Type1Uki = 1 << 16;
41+
/// Bootloader supports type-1 UKI urls.
42+
const Type1UkiUrl = 1 << 17;
43+
/// Bootloader indicates TPM2 active PCR banks.
44+
const Tpm2ActivePcrBanks = 1 << 18;
45+
}
46+
}

src/utils/variables.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,10 @@ impl VariableController {
9898
pub fn set_bool(&self, key: &str, value: bool, class: VariableClass) -> Result<()> {
9999
self.set(key, &[value as u8], class)
100100
}
101+
102+
/// Set the u64 little-endian variable specified by `key` to `value`.
103+
/// The variable `class` controls the attributes for the variable.
104+
pub fn set_u64le(&self, key: &str, value: u64, class: VariableClass) -> Result<()> {
105+
self.set(key, &value.to_le_bytes(), class)
106+
}
101107
}

0 commit comments

Comments
 (0)