2025-10-01 18:25:49 -07:00
|
|
|
use crate::config::ChainloaderConfiguration;
|
2025-10-01 21:30:43 -07:00
|
|
|
use crate::utils::text_to_device_path;
|
2025-10-01 19:15:42 -07:00
|
|
|
use log::info;
|
2025-10-01 21:30:43 -07:00
|
|
|
use uefi::proto::device_path::{
|
|
|
|
|
DevicePath, LoadedImageDevicePath,
|
|
|
|
|
text::{AllowShortcuts, DisplayOnly},
|
2025-10-01 16:45:04 -07:00
|
|
|
};
|
2025-10-01 21:30:43 -07:00
|
|
|
use uefi::proto::loaded_image::LoadedImage;
|
2025-10-01 16:45:04 -07:00
|
|
|
|
2025-10-01 18:25:49 -07:00
|
|
|
pub fn chainloader(configuration: ChainloaderConfiguration) {
|
2025-10-01 16:45:04 -07:00
|
|
|
let sprout_image = uefi::boot::image_handle();
|
|
|
|
|
let image_device_path_protocol =
|
|
|
|
|
uefi::boot::open_protocol_exclusive::<LoadedImageDevicePath>(sprout_image)
|
2025-10-01 19:15:42 -07:00
|
|
|
.expect("unable to open loaded image device path protocol");
|
2025-10-01 16:45:04 -07:00
|
|
|
|
|
|
|
|
let image_device_path: &DevicePath = &image_device_path_protocol;
|
|
|
|
|
let mut full_path = image_device_path
|
|
|
|
|
.node_iter()
|
|
|
|
|
.filter_map(|item| {
|
|
|
|
|
let item = item
|
|
|
|
|
.to_string(DisplayOnly(false), AllowShortcuts(false))
|
|
|
|
|
.expect("unable to convert device path to string");
|
|
|
|
|
if item.to_string().contains("(") {
|
|
|
|
|
Some(item)
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.map(|item| item.to_string())
|
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
|
.join("/");
|
|
|
|
|
full_path.push('/');
|
2025-10-01 18:25:49 -07:00
|
|
|
full_path.push_str(&configuration.path);
|
2025-10-01 16:45:04 -07:00
|
|
|
|
2025-10-01 19:15:42 -07:00
|
|
|
info!("path={}", full_path);
|
2025-10-01 16:45:04 -07:00
|
|
|
|
|
|
|
|
let device_path = 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,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.expect("failed to load image");
|
2025-10-01 19:15:42 -07:00
|
|
|
|
|
|
|
|
let image_device_path_protocol = uefi::boot::open_protocol_exclusive::<LoadedImage>(image)
|
|
|
|
|
.expect("unable to open loaded image protocol");
|
|
|
|
|
|
|
|
|
|
let (base, size) = image_device_path_protocol.info();
|
|
|
|
|
info!("loaded image base={:#x} size={:#x}", base.addr(), size);
|
2025-10-01 16:45:04 -07:00
|
|
|
uefi::boot::start_image(image).expect("failed to start image");
|
|
|
|
|
}
|