implement driver loading

This commit is contained in:
2025-10-12 22:39:56 -07:00
parent ea5737c6d0
commit aba53c0d2b
3 changed files with 78 additions and 0 deletions

View File

@@ -1,4 +1,5 @@
use crate::actions::ActionDeclaration; use crate::actions::ActionDeclaration;
use crate::drivers::DriverDeclaration;
use crate::generators::GeneratorDeclaration; use crate::generators::GeneratorDeclaration;
use crate::utils; use crate::utils;
use anyhow::Context; use anyhow::Context;
@@ -13,6 +14,8 @@ pub struct RootConfiguration {
#[serde(default)] #[serde(default)]
pub values: BTreeMap<String, String>, pub values: BTreeMap<String, String>,
#[serde(default)] #[serde(default)]
pub drivers: BTreeMap<String, DriverDeclaration>,
#[serde(default)]
pub actions: BTreeMap<String, ActionDeclaration>, pub actions: BTreeMap<String, ActionDeclaration>,
#[serde(default)] #[serde(default)]
pub entries: BTreeMap<String, EntryDeclaration>, pub entries: BTreeMap<String, EntryDeclaration>,

72
src/drivers.rs Normal file
View File

@@ -0,0 +1,72 @@
use crate::context::SproutContext;
use crate::utils;
use anyhow::{Context, Result};
use log::info;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::rc::Rc;
use uefi::boot::SearchType;
use uefi::proto::device_path::LoadedImageDevicePath;
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct DriverDeclaration {
pub path: String,
}
fn load_driver(context: Rc<SproutContext>, driver: &DriverDeclaration) -> Result<()> {
let sprout_image = uefi::boot::image_handle();
let image_device_path_protocol =
uefi::boot::open_protocol_exclusive::<LoadedImageDevicePath>(sprout_image)
.context("unable to open loaded image device path protocol")?;
let mut full_path = utils::device_path_root(&image_device_path_protocol)?;
full_path.push_str(&context.stamp(&driver.path));
info!("driver path: {}", full_path);
let device_path = utils::text_to_device_path(&full_path)?;
let image = uefi::boot::load_image(
sprout_image,
uefi::boot::LoadImageSource::FromDevicePath {
device_path: &device_path,
boot_policy: uefi::proto::BootPolicy::ExactMatch,
},
)
.context("failed to load image")?;
uefi::boot::start_image(image).context("failed to start driver image")?;
Ok(())
}
fn reconnect() -> Result<()> {
let handles = uefi::boot::locate_handle_buffer(SearchType::AllHandles)
.context("failed to locate handles buffer")?;
for handle in handles.iter() {
// ignore result as there is nothing we can do if it doesn't work.
let _ = uefi::boot::connect_controller(*handle, None, None, true);
}
Ok(())
}
pub fn load(
context: Rc<SproutContext>,
drivers: &BTreeMap<String, DriverDeclaration>,
) -> Result<()> {
if drivers.is_empty() {
return Ok(());
}
info!("loading drivers");
for (name, driver) in drivers {
load_driver(context.clone(), driver).context(format!("failed to load driver: {}", name))?;
}
reconnect().context("failed to reconnect drivers")?;
info!("loaded drivers");
Ok(())
}

View File

@@ -9,6 +9,7 @@ use std::rc::Rc;
pub mod actions; pub mod actions;
pub mod config; pub mod config;
pub mod context; pub mod context;
pub mod drivers;
pub mod generators; pub mod generators;
pub mod setup; pub mod setup;
pub mod utils; pub mod utils;
@@ -43,6 +44,8 @@ fn main() -> Result<()> {
context.insert(&config.values); context.insert(&config.values);
let context = context.freeze(); let context = context.freeze();
drivers::load(context.clone(), &config.drivers).context("failed to load drivers")?;
phase(context.clone(), &config.phases.startup)?; phase(context.clone(), &config.phases.startup)?;
let mut all_entries = Vec::new(); let mut all_entries = Vec::new();