mirror of
https://github.com/edera-dev/sprout.git
synced 2025-12-19 15:20:17 +00:00
feat(bootloader-interface): implement support for LoaderImageIdentifier
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
use crate::platform::timer::PlatformTimer;
|
use crate::platform::timer::PlatformTimer;
|
||||||
|
use crate::utils::device_path_subpath;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
use uefi::proto::device_path::DevicePath;
|
||||||
use uefi::{CString16, Guid, guid};
|
use uefi::{CString16, Guid, guid};
|
||||||
use uefi_raw::table::runtime::{VariableAttributes, VariableVendor};
|
use uefi_raw::table::runtime::{VariableAttributes, VariableVendor};
|
||||||
|
|
||||||
@@ -28,6 +30,12 @@ impl BootloaderInterface {
|
|||||||
Self::set_cstr16(key, &elapsed.as_micros().to_string())
|
Self::set_cstr16(key, &elapsed.as_micros().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tell the system the relative path to the partition root of the current bootloader.
|
||||||
|
pub fn set_loader_path(path: &DevicePath) -> Result<()> {
|
||||||
|
let subpath = device_path_subpath(path).context("unable to get loader path subpath")?;
|
||||||
|
Self::set_cstr16("LoaderImageIdentifier", &subpath)
|
||||||
|
}
|
||||||
|
|
||||||
/// Tell the system what the partition GUID of the ESP Sprout was booted from is.
|
/// Tell the system what the partition GUID of the ESP Sprout was booted from is.
|
||||||
pub fn set_partition_guid(guid: &Guid) -> Result<()> {
|
pub fn set_partition_guid(guid: &Guid) -> Result<()> {
|
||||||
Self::set_cstr16("LoaderDevicePartUUID", &guid.to_string())
|
Self::set_cstr16("LoaderDevicePartUUID", &guid.to_string())
|
||||||
@@ -39,11 +47,14 @@ impl BootloaderInterface {
|
|||||||
// Iterate over the entries and convert them to CString16 placing them into data.
|
// Iterate over the entries and convert them to CString16 placing them into data.
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
// Convert the entry to a CString16.
|
// Convert the entry to CString16 little endian.
|
||||||
let entry = CString16::try_from(entry.as_ref())
|
let encoded = entry
|
||||||
.context("unable to convert entry to CString16")?;
|
.as_ref()
|
||||||
|
.encode_utf16()
|
||||||
|
.flat_map(|c| c.to_le_bytes())
|
||||||
|
.collect::<Vec<u8>>();
|
||||||
// Write the bytes (including the null terminator) into the data buffer.
|
// Write the bytes (including the null terminator) into the data buffer.
|
||||||
data.extend_from_slice(entry.as_bytes());
|
data.extend_from_slice(&encoded);
|
||||||
}
|
}
|
||||||
Self::set("LoaderEntries", &data)
|
Self::set("LoaderEntries", &data)
|
||||||
}
|
}
|
||||||
@@ -91,8 +102,11 @@ impl BootloaderInterface {
|
|||||||
/// Set a bootloader interface variable specified by `key` to `value`, converting the value to
|
/// Set a bootloader interface variable specified by `key` to `value`, converting the value to
|
||||||
/// a [CString16].
|
/// a [CString16].
|
||||||
fn set_cstr16(key: &str, value: &str) -> Result<()> {
|
fn set_cstr16(key: &str, value: &str) -> Result<()> {
|
||||||
let value =
|
// Encode the value as a CString16 little endian.
|
||||||
CString16::try_from(value).context("unable to convert variable value to CString16")?;
|
let encoded = value
|
||||||
Self::set(key, value.as_bytes())
|
.encode_utf16()
|
||||||
|
.flat_map(|c| c.to_le_bytes())
|
||||||
|
.collect::<Vec<u8>>();
|
||||||
|
Self::set(key, &encoded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,10 @@ fn run() -> Result<()> {
|
|||||||
.context("unable to set partition guid in bootloader interface")?;
|
.context("unable to set partition guid in bootloader interface")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tell the bootloader interface what the loaded image path is.
|
||||||
|
BootloaderInterface::set_loader_path(&loaded_image_path)
|
||||||
|
.context("unable to set loader path in bootloader interface")?;
|
||||||
|
|
||||||
// Create the root context.
|
// Create the root context.
|
||||||
let mut root = RootContext::new(loaded_image_path, timer, options);
|
let mut root = RootContext::new(loaded_image_path, timer, options);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user