uefi update

This commit is contained in:
2025-07-02 00:51:00 +02:00
parent a59b723f4b
commit f6ebf675bc
9 changed files with 98 additions and 159 deletions

79
Cargo.lock generated
View File

@ -4,10 +4,9 @@ version = 4
[[package]] [[package]]
name = "barnacle" name = "barnacle"
version = "0.3.0" version = "1.0.0"
dependencies = [ dependencies = [
"uefi", "uefi",
"uefi-services",
] ]
[[package]] [[package]]
@ -18,76 +17,65 @@ checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.4.1" version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.20" version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "ptr_meta" name = "ptr_meta"
version = "0.2.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcada80daa06c42ed5f48c9a043865edea5dc44cbf9ac009fda3b89526e28607" checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90"
dependencies = [ dependencies = [
"ptr_meta_derive", "ptr_meta_derive",
] ]
[[package]] [[package]]
name = "ptr_meta_derive" name = "ptr_meta_derive"
version = "0.2.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bca9224df2e20e7c5548aeb5f110a0f3b77ef05f8585139b7148b59056168ed2" checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.33" version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "2.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -105,11 +93,12 @@ dependencies = [
[[package]] [[package]]
name = "uefi" name = "uefi"
version = "0.26.0" version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07ead9f748a4646479b850add36b527113a80e80a7e0f44d7b0334291850dcc5" checksum = "da7569ceafb898907ff764629bac90ac24ba4203c38c33ef79ee88c74aa35b11"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cfg-if",
"log", "log",
"ptr_meta", "ptr_meta",
"ucs2", "ucs2",
@ -120,37 +109,25 @@ dependencies = [
[[package]] [[package]]
name = "uefi-macros" name = "uefi-macros"
version = "0.13.0" version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26a7b1c2c808c3db854a54d5215e3f7e7aaf5dcfbce095598cba6af29895695d" checksum = "b3dad47b3af8f99116c0f6d4d669c439487d9aaf1c8d9480d686cda6f3a8aa23"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn",
] ]
[[package]] [[package]]
name = "uefi-raw" name = "uefi-raw"
version = "0.5.2" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efa8716f52e8cab8bcedfd5052388a0f263b69fe5cc2561548dc6a530678333c" checksum = "7cad96b8baaf1615d3fdd0f03d04a0b487d857c1b51b19dcbfe05e2e3c447b78"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"ptr_meta",
"uguid", "uguid",
] ]
[[package]]
name = "uefi-services"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a79fcb420624743c895bad0f9480fbc2f64e7c8d8611fb1ada6bdd799942feb4"
dependencies = [
"cfg-if",
"log",
"uefi",
]
[[package]] [[package]]
name = "uguid" name = "uguid"
version = "2.2.0" version = "2.2.0"
@ -159,6 +136,6 @@ checksum = "ab14ea9660d240e7865ce9d54ecdbd1cd9fa5802ae6f4512f093c7907e921533"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.12" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

View File

@ -1,10 +1,9 @@
[package] [package]
name = "barnacle" name = "barnacle"
version = "0.3.0" version = "1.0.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
uefi = "0.26.0" uefi = "0.35.0"
uefi-services = "0.23.0"

View File

@ -1,7 +1,7 @@
use core::{ffi::c_void, mem::MaybeUninit}; use core::{ffi::c_void, mem::MaybeUninit};
use uefi::{ use uefi::{
prelude::BootServices, boot,
proto::device_path::{build, DevicePath}, proto::device_path::{build, DevicePath},
Guid, Identify, Status, Guid, Identify, Status,
}; };
@ -28,23 +28,17 @@ pub fn make_loader(pointer: *const c_void, size: usize) -> Loader {
/// Installs the initrd virtual device /// Installs the initrd virtual device
/// Uses a buffer to build the device path /// Uses a buffer to build the device path
/// Creates a callback to initrd_loadfile2 for the kernel /// Creates a callback to initrd_loadfile2 for the kernel
pub fn install_initrd( pub fn install_initrd(buf: &mut [MaybeUninit<u8>; 256], mut loader: Loader) {
boot_services: &BootServices,
buf: &mut [MaybeUninit<u8>; 256],
mut loader: Loader,
) {
unsafe { unsafe {
// Define new virtual device // Define new virtual device
let initrd_handle = boot_services let initrd_handle = boot::install_protocol_interface(
.install_protocol_interface(
None, None,
&DevicePath::GUID, &DevicePath::GUID,
make_initrd_device_path(buf).as_ffi_ptr() as *mut c_void, make_initrd_device_path(buf).as_ffi_ptr() as *mut c_void,
) )
.unwrap(); .unwrap();
// Install LoadFile2 protocol and callback // Install LoadFile2 protocol and callback
boot_services boot::install_protocol_interface(
.install_protocol_interface(
Some(initrd_handle), Some(initrd_handle),
&LOADFILE2_GUID, &LOADFILE2_GUID,
core::ptr::addr_of_mut!(loader) as *mut c_void, core::ptr::addr_of_mut!(loader) as *mut c_void,

View File

@ -2,8 +2,7 @@
use linux::start_linux; use linux::start_linux;
use pe::get_loader_sections; use pe::get_loader_sections;
use uefi::table::{Boot, SystemTable}; use uefi::{boot, Handle, Status};
use uefi::{Handle, Status};
mod initrd; mod initrd;
mod linux; mod linux;
@ -17,11 +16,10 @@ pub fn panic(_: &core::panic::PanicInfo) -> ! {
loop {} loop {}
} }
pub fn bootloader(image_handle: Handle, system_table: SystemTable<Boot>) -> Status { pub fn bootloader(image_handle: Handle) -> Status {
let boot_services = system_table.boot_services(); let sections = get_loader_sections(image_handle).unwrap();
let sections = get_loader_sections(boot_services).unwrap(); start_linux(image_handle, sections).unwrap();
start_linux(image_handle, boot_services, sections).unwrap();
boot_services.stall(1_000_000_000); boot::stall(1_000_000_000);
Status::SUCCESS Status::SUCCESS
} }

View File

@ -1,9 +1,6 @@
use core::{ffi::c_void, mem::MaybeUninit, ptr::slice_from_raw_parts}; use core::{ffi::c_void, mem::MaybeUninit, ptr::slice_from_raw_parts};
use uefi::{ use uefi::{boot, proto::loaded_image::LoadedImage, Handle, Result};
prelude::BootServices, proto::loaded_image::LoadedImage, table::boot::LoadImageSource, Handle,
Result,
};
use crate::{ use crate::{
initrd::{install_initrd, make_loader}, initrd::{install_initrd, make_loader},
@ -15,18 +12,13 @@ use crate::{
/// Sets up linux image and initrd virtual device /// Sets up linux image and initrd virtual device
/// Reads cmdline /// Reads cmdline
/// Runs kernel /// Runs kernel
pub fn start_linux( pub fn start_linux(image_handle: Handle, sections: BootSections) -> Result {
image_handle: Handle,
boot_services: &BootServices,
sections: BootSections,
) -> Result {
// Load kernel as image from memory ignoring secure boot // Load kernel as image from memory ignoring secure boot
// Image is already trusted (signed) by being part of this EFI program // Image is already trusted (signed) by being part of this EFI program
let handle = run_in_security_override(boot_services, || { let handle = run_in_security_override(|| {
boot_services boot::load_image(
.load_image(
image_handle, image_handle,
LoadImageSource::FromBuffer { boot::LoadImageSource::FromBuffer {
buffer: unsafe { buffer: unsafe {
&*slice_from_raw_parts::<u8>( &*slice_from_raw_parts::<u8>(
sections.linux.pointer, sections.linux.pointer,
@ -39,16 +31,11 @@ pub fn start_linux(
.unwrap() .unwrap()
})?; })?;
let mut linux_image = boot_services let mut linux_image = boot::open_protocol_exclusive::<LoadedImage>(handle).unwrap();
.open_protocol_exclusive::<LoadedImage>(handle)
.unwrap();
// Set cmdline for kernel image (expected as utf16) // Set cmdline for kernel image (expected as utf16)
let (cmdline_utf16, cmdline_utf16_size) = convert_8_to_16( let (cmdline_utf16, cmdline_utf16_size) =
boot_services, convert_8_to_16(sections.cmdline.pointer, sections.cmdline.size as usize);
sections.cmdline.pointer,
sections.cmdline.size as usize,
);
unsafe { linux_image.set_load_options(cmdline_utf16, cmdline_utf16_size as u32) }; unsafe { linux_image.set_load_options(cmdline_utf16, cmdline_utf16_size as u32) };
// Define loader for virtual initrd device // Define loader for virtual initrd device
@ -61,10 +48,10 @@ pub fn start_linux(
// Install virtual initrd device // Install virtual initrd device
// Buffer is used to build the device path, also needs to exist here for lifespan reasons // Buffer is used to build the device path, also needs to exist here for lifespan reasons
let mut buf = [MaybeUninit::<u8>::uninit(); 256]; let mut buf = [MaybeUninit::<u8>::uninit(); 256];
install_initrd(boot_services, &mut buf, loader); install_initrd(&mut buf, loader);
// Run kernel image // Run kernel image
boot_services.start_image(handle).unwrap(); boot::start_image(handle).unwrap();
Ok(()) Ok(())
} }

View File

@ -3,11 +3,12 @@
use barnacle::bootloader; use barnacle::bootloader;
use uefi::boot;
use uefi::prelude::entry; use uefi::prelude::entry;
use uefi::table::{Boot, SystemTable}; use uefi::Status;
use uefi::{Handle, Status};
#[entry] #[entry]
fn main(image_handle: Handle, system_table: SystemTable<Boot>) -> Status { fn main() -> Status {
bootloader(image_handle, system_table) let image_handle = boot::image_handle();
bootloader(image_handle)
} }

View File

@ -1,6 +1,5 @@
use uefi::prelude::BootServices;
use uefi::proto::loaded_image::LoadedImage; use uefi::proto::loaded_image::LoadedImage;
use uefi::{Error, Result, Status}; use uefi::{boot, Error, Handle, Result, Status};
const LINUX_SNAME: [u8; 8] = *b".linux\0\0"; const LINUX_SNAME: [u8; 8] = *b".linux\0\0";
const CMDLINE_SNAME: [u8; 8] = *b".cmdline"; const CMDLINE_SNAME: [u8; 8] = *b".cmdline";
@ -25,10 +24,9 @@ pub struct BootSections {
} }
/// Extracts .linux, .initrd, and .cmdline sections from UKI /// Extracts .linux, .initrd, and .cmdline sections from UKI
pub fn get_loader_sections(boot_services: &BootServices) -> Result<BootSections> { pub fn get_loader_sections(image_handle: Handle) -> Result<BootSections> {
// Obtain current image (UKI) memory location (and size) // Obtain current image (UKI) memory location (and size)
let loaded_image = let loaded_image = boot::open_protocol_exclusive::<LoadedImage>(image_handle)?;
boot_services.open_protocol_exclusive::<LoadedImage>(boot_services.image_handle())?;
let (image_ptr, _image_size) = loaded_image.info(); let (image_ptr, _image_size) = loaded_image.info();
let mut tmp_sections = TempSections { let mut tmp_sections = TempSections {

View File

@ -1,6 +1,6 @@
use core::ffi::c_void; use core::ffi::c_void;
use uefi::{prelude::BootServices, proto::unsafe_protocol, Result}; use uefi::{boot, proto::unsafe_protocol, Result};
#[unsafe_protocol("A46423E3-4617-49F1-B9FF-D1BFA9115839")] #[unsafe_protocol("A46423E3-4617-49F1-B9FF-D1BFA9115839")]
struct SecurityArch { struct SecurityArch {
@ -21,10 +21,7 @@ fn security_handler() -> bool {
/// Runs a function with a blind secure boot validator /// Runs a function with a blind secure boot validator
/// Plagiarized from systemd-stub's "hack" /// Plagiarized from systemd-stub's "hack"
/// There must be a better way /// There must be a better way
pub fn run_in_security_override<R, T: Fn() -> R>( pub fn run_in_security_override<R, T: Fn() -> R>(function: T) -> Result<R> {
boot_services: &BootServices,
function: T,
) -> Result<R> {
// Temporary storage for restoration later // Temporary storage for restoration later
let mut df_security1 = None; let mut df_security1 = None;
let mut df_security1_handler = None; let mut df_security1_handler = None;
@ -32,12 +29,8 @@ pub fn run_in_security_override<R, T: Fn() -> R>(
let mut df_security2_handler = None; let mut df_security2_handler = None;
// Obtain SecurityArch protocol and replace handler // Obtain SecurityArch protocol and replace handler
boot_services boot::get_handle_for_protocol::<SecurityArch>().map(|h| {
.get_handle_for_protocol::<SecurityArch>() boot::open_protocol_exclusive::<SecurityArch>(h).map(|mut security| {
.map(|h| {
boot_services
.open_protocol_exclusive::<SecurityArch>(h)
.map(|mut security| {
df_security1 = Some(core::ptr::addr_of_mut!(security.handler)); df_security1 = Some(core::ptr::addr_of_mut!(security.handler));
df_security1_handler = Some(security.handler); df_security1_handler = Some(security.handler);
security.handler = security_handler as *const c_void; security.handler = security_handler as *const c_void;
@ -45,12 +38,8 @@ pub fn run_in_security_override<R, T: Fn() -> R>(
})??; })??;
// Obtain Security2Arch protocol and replace handler // Obtain Security2Arch protocol and replace handler
boot_services boot::get_handle_for_protocol::<Security2Arch>().map(|h| {
.get_handle_for_protocol::<Security2Arch>() boot::open_protocol_exclusive::<Security2Arch>(h).map(|mut security| {
.map(|h| {
boot_services
.open_protocol_exclusive::<Security2Arch>(h)
.map(|mut security| {
df_security2 = Some(core::ptr::addr_of_mut!(security.handler)); df_security2 = Some(core::ptr::addr_of_mut!(security.handler));
df_security2_handler = Some(security.handler); df_security2_handler = Some(security.handler);
security.handler = security_handler as *const c_void; security.handler = security_handler as *const c_void;

View File

@ -1,14 +1,10 @@
use uefi::{prelude::BootServices, table::boot::MemoryType}; use uefi::boot;
/// Converts ascii to basic utf-16 /// Converts ascii to basic utf-16
pub fn convert_8_to_16( pub fn convert_8_to_16(text: *const u8, size: usize) -> (*const u8, usize) {
boot_services: &BootServices, let work_mem = boot::allocate_pool(boot::MemoryType::BOOT_SERVICES_DATA, size * 2)
text: *const u8, .unwrap()
size: usize, .as_ptr() as *mut u16;
) -> (*const u8, usize) {
let work_mem = boot_services
.allocate_pool(MemoryType::BOOT_SERVICES_DATA, size * 2)
.unwrap() as *mut u16;
for i in 0..size { for i in 0..size {
unsafe { unsafe {
*work_mem.add(i) = *text.add(i) as u16; *work_mem.add(i) = *text.add(i) as u16;