From 54153f0ecc1e6529f4c710a1e39115930437f729 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 16 Jun 2026 08:34:05 +0200 Subject: [PATCH] uefi: bump from 0.20 to 0.37 --- Cargo.lock | 66 +++---- uefi/Cargo.toml | 2 +- uefi/src/main.rs | 317 ++++++++++------------------------ uefi/src/memory_descriptor.rs | 2 +- 4 files changed, 132 insertions(+), 255 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bcb31226..34fc1293 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -484,7 +484,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.117", + "syn", ] [[package]] @@ -498,22 +498,22 @@ dependencies = [ [[package]] name = "ptr_meta" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcada80daa06c42ed5f48c9a043865edea5dc44cbf9ac009fda3b89526e28607" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" dependencies = [ "ptr_meta_derive", ] [[package]] name = "ptr_meta_derive" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca9224df2e20e7c5548aeb5f110a0f3b77ef05f8585139b7148b59056168ed2" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -687,7 +687,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -734,17 +734,6 @@ dependencies = [ "vte", ] -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.117" @@ -891,7 +880,7 @@ checksum = "d14928354b01c4d6a4f0e549069adef399a284e7995c7ccca94e8a07a5346c59" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -918,37 +907,56 @@ dependencies = [ [[package]] name = "ucs2" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad643914094137d475641b6bab89462505316ec2ce70907ad20102d28a79ab8" +checksum = "df79298e11f316400c57ec268f3c2c29ac3c4d4777687955cd3d4f3a35ce7eba" dependencies = [ "bit_field", ] [[package]] name = "uefi" -version = "0.20.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab39d5e7740f21ed4c46d6659f31038bbe3fe7a8be1f702d8a984348837c43b1" +checksum = "66ab9569afdd1e33a31d8002343aa1df594f055347b1a66136bf9dd6cbc3ec37" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.11.1", + "cfg-if", "log", "ptr_meta", "ucs2", "uefi-macros", + "uefi-raw", + "uguid", ] [[package]] name = "uefi-macros" -version = "0.11.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0caeb0e7b31b9f1f347e541106be10aa8c66c76fa722a3298a4cd21433fabd4" +checksum = "4687412b5ac74d245d5bfb1733ede50c31be19bf8a4b6a967a29b451bab49e67" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] +[[package]] +name = "uefi-raw" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3775e5934877acaef4b00f254f252df1e2266903c31e51455c117f4f2824eda" +dependencies = [ + "bitflags 2.11.1", + "uguid", +] + +[[package]] +name = "uguid" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8352f8c05e47892e7eaf13b34abd76a7f4aeaf817b716e88789381927f199c" + [[package]] name = "unicode-ident" version = "1.0.10" @@ -1118,7 +1126,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.117", + "syn", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -1134,7 +1142,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.117", + "syn", "wit-bindgen-core", "wit-bindgen-rust", ] diff --git a/uefi/Cargo.toml b/uefi/Cargo.toml index 99128c74..3be002f2 100644 --- a/uefi/Cargo.toml +++ b/uefi/Cargo.toml @@ -15,4 +15,4 @@ bootloader-boot-config = { workspace = true } log = "0.4.14" x86_64 = "0.15.2" serde-json-core = "0.5.0" -uefi = "0.20.0" +uefi = "0.37.0" diff --git a/uefi/src/main.rs b/uefi/src/main.rs index 564c374c..6b28156b 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -8,30 +8,21 @@ use bootloader_boot_config::BootConfig; use bootloader_x86_64_common::{ Kernel, RawFrameBufferInfo, SystemInfo, legacy_memory_region::LegacyFrameAllocator, }; -use core::{ - cell::UnsafeCell, - ops::{Deref, DerefMut}, - ptr, slice, -}; +use core::net::Ipv4Addr; +use core::{ptr, slice}; +use uefi::mem::memory_map::{MemoryMap, MemoryMapMut}; +use uefi::table::cfg::ConfigTableEntry; use uefi::{ - CStr8, CStr16, - prelude::{Boot, Handle, Status, SystemTable, entry}, + CStr8, CStr16, boot, + boot::{AllocateType, MemoryType, OpenProtocolAttributes, OpenProtocolParams}, + prelude::{Status, entry}, proto::{ - ProtocolPointer, console::gop::{GraphicsOutput, PixelFormat}, - device_path::DevicePath, - loaded_image::LoadedImage, media::{ file::{File, FileAttribute, FileInfo, FileMode}, fs::SimpleFileSystem, }, - network::{ - IpAddress, - pxe::{BaseCode, DhcpV4Packet}, - }, - }, - table::boot::{ - AllocateType, MemoryType, OpenProtocolAttributes, OpenProtocolParams, ScopedProtocol, + network::pxe::{BaseCode, DhcpV4Packet}, }, }; use x86_64::{ @@ -41,48 +32,19 @@ use x86_64::{ mod memory_descriptor; -static SYSTEM_TABLE: RacyCell>> = RacyCell::new(None); - -struct RacyCell(UnsafeCell); - -impl RacyCell { - const fn new(v: T) -> Self { - Self(UnsafeCell::new(v)) - } -} - -unsafe impl Sync for RacyCell {} - -impl core::ops::Deref for RacyCell { - type Target = UnsafeCell; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - #[entry] -fn efi_main(image: Handle, st: SystemTable) -> Status { - main_inner(image, st) -} - -fn main_inner(image: Handle, mut st: SystemTable) -> Status { - // temporarily clone the y table for printing panics - unsafe { - *SYSTEM_TABLE.get() = Some(st.unsafe_clone()); - } - +fn main() -> Status { let mut boot_mode = BootMode::Disk; - let mut kernel = load_kernel(image, &mut st, boot_mode); + let mut kernel = load_kernel(boot_mode); if kernel.is_none() { // Try TFTP boot boot_mode = BootMode::Tftp; - kernel = load_kernel(image, &mut st, boot_mode); + kernel = load_kernel(boot_mode); } let kernel = kernel.expect("Failed to load kernel"); - let config_file = load_config_file(image, &mut st, boot_mode); + let config_file = load_config_file(boot_mode); let mut error_loading_config: Option = None; let mut config: BootConfig = match config_file .as_deref() @@ -106,11 +68,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { config.frame_buffer.minimum_framebuffer_width = kernel.config.frame_buffer.minimum_framebuffer_width; } - let framebuffer = init_logger(image, &st, &config); - - unsafe { - *SYSTEM_TABLE.get() = None; - } + let framebuffer = init_logger(&config); log::info!("UEFI bootloader started"); @@ -126,7 +84,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { log::info!("Trying to load ramdisk via {:?}", boot_mode); // Ramdisk must load from same source, or not at all. - let ramdisk = load_ramdisk(image, &mut st, boot_mode); + let ramdisk = load_ramdisk(boot_mode); log::info!( "{}", @@ -137,7 +95,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { ); log::trace!("exiting boot services"); - let (system_table, mut memory_map) = st.exit_boot_services(); + let mut memory_map = unsafe { boot::exit_boot_services(None) }; memory_map.sort(); @@ -156,14 +114,19 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { let system_info = SystemInfo { framebuffer, rsdp_addr: { - use uefi::table::cfg; - let mut config_entries = system_table.config_table().iter(); - // look for an ACPI2 RSDP first - let acpi2_rsdp = config_entries.find(|entry| matches!(entry.guid, cfg::ACPI2_GUID)); - // if no ACPI2 RSDP is found, look for a ACPI1 RSDP - let rsdp = acpi2_rsdp - .or_else(|| config_entries.find(|entry| matches!(entry.guid, cfg::ACPI_GUID))); - rsdp.map(|entry| PhysAddr::new(entry.address as u64)) + uefi::system::with_config_table(|config_entries| { + // look for an ACPI2 RSDP first + let acpi2_rsdp = config_entries + .iter() + .find(|entry| matches!(entry.guid, ConfigTableEntry::ACPI2_GUID)); + // if no ACPI2 RSDP is found, look for a ACPI1 RSDP + let rsdp = acpi2_rsdp.or_else(|| { + config_entries + .iter() + .find(|entry| matches!(entry.guid, ConfigTableEntry::ACPI_GUID)) + }); + rsdp.map(|entry| PhysAddr::new(entry.address as u64)) + }) }, ramdisk_addr, ramdisk_len, @@ -184,126 +147,38 @@ pub enum BootMode { Tftp, } -fn load_ramdisk( - image: Handle, - st: &mut SystemTable, - boot_mode: BootMode, -) -> Option<&'static mut [u8]> { - load_file_from_boot_method(image, st, "ramdisk\0", boot_mode) +fn load_ramdisk(boot_mode: BootMode) -> Option<&'static mut [u8]> { + load_file_from_boot_method("ramdisk\0", boot_mode) } -fn load_config_file( - image: Handle, - st: &mut SystemTable, - boot_mode: BootMode, -) -> Option<&'static mut [u8]> { - load_file_from_boot_method(image, st, "boot.json\0", boot_mode) +fn load_config_file(boot_mode: BootMode) -> Option<&'static mut [u8]> { + load_file_from_boot_method("boot.json\0", boot_mode) } -fn load_kernel( - image: Handle, - st: &mut SystemTable, - boot_mode: BootMode, -) -> Option> { - let kernel_slice = load_file_from_boot_method(image, st, "kernel-x86_64\0", boot_mode)?; +fn load_kernel(boot_mode: BootMode) -> Option> { + let kernel_slice = load_file_from_boot_method("kernel-x86_64\0", boot_mode)?; Some(Kernel::parse(kernel_slice)) } -fn load_file_from_boot_method( - image: Handle, - st: &mut SystemTable, - filename: &str, - boot_mode: BootMode, -) -> Option<&'static mut [u8]> { +fn load_file_from_boot_method(filename: &str, boot_mode: BootMode) -> Option<&'static mut [u8]> { match boot_mode { - BootMode::Disk => load_file_from_disk(filename, image, st), - BootMode::Tftp => load_file_from_tftp_boot_server(filename, image, st), + BootMode::Disk => load_file_from_disk(filename), + BootMode::Tftp => load_file_from_tftp_boot_server(filename), } } -fn open_device_path_protocol( - image: Handle, - st: &SystemTable, -) -> Option> { - let this = st.boot_services(); - let loaded_image = unsafe { - this.open_protocol::( +fn load_file_from_disk(name: &str) -> Option<&'static mut [u8]> { + let mut file_system = unsafe { + boot::open_protocol::( OpenProtocolParams { - handle: image, - agent: image, + handle: uefi::boot::image_handle(), + agent: uefi::boot::image_handle(), controller: None, }, - OpenProtocolAttributes::Exclusive, + OpenProtocolAttributes::GetProtocol, ) - }; - - if loaded_image.is_err() { - log::error!("Failed to open protocol LoadedImage"); - return None; } - let loaded_image = loaded_image.unwrap(); - let loaded_image = loaded_image.deref(); - - let device_handle = loaded_image.device(); - - let device_path = unsafe { - this.open_protocol::( - OpenProtocolParams { - handle: device_handle, - agent: image, - controller: None, - }, - OpenProtocolAttributes::Exclusive, - ) - }; - if device_path.is_err() { - log::error!("Failed to open protocol DevicePath"); - return None; - } - Some(device_path.unwrap()) -} - -fn locate_and_open_protocol( - image: Handle, - st: &SystemTable, -) -> Option> { - let this = st.boot_services(); - let device_path = open_device_path_protocol(image, st)?; - let mut device_path = device_path.deref(); - - let fs_handle = this.locate_device_path::

(&mut device_path); - if fs_handle.is_err() { - log::error!("Failed to open device path"); - return None; - } - - let fs_handle = fs_handle.unwrap(); - - let opened_handle = unsafe { - this.open_protocol::

( - OpenProtocolParams { - handle: fs_handle, - agent: image, - controller: None, - }, - OpenProtocolAttributes::Exclusive, - ) - }; - - if opened_handle.is_err() { - log::error!("Failed to open protocol {}", core::any::type_name::

()); - return None; - } - Some(opened_handle.unwrap()) -} - -fn load_file_from_disk( - name: &str, - image: Handle, - st: &SystemTable, -) -> Option<&'static mut [u8]> { - let mut file_system_raw = locate_and_open_protocol::(image, st)?; - let file_system = file_system_raw.deref_mut(); + .ok()?; let mut root = file_system.open_volume().unwrap(); let mut buf = [0u16; 256]; @@ -324,57 +199,60 @@ fn load_file_from_disk( let file_info: &mut FileInfo = file.get_info(&mut buf).unwrap(); let file_size = usize::try_from(file_info.file_size()).unwrap(); - let file_ptr = st - .boot_services() - .allocate_pages( - AllocateType::AnyPages, - MemoryType::LOADER_DATA, - ((file_size - 1) / 4096) + 1, - ) - .unwrap() as *mut u8; - unsafe { ptr::write_bytes(file_ptr, 0, file_size) }; - let file_slice = unsafe { slice::from_raw_parts_mut(file_ptr, file_size) }; + let mut file_ptr = boot::allocate_pages( + AllocateType::AnyPages, + MemoryType::LOADER_DATA, + ((file_size - 1) / 4096) + 1, + ) + .unwrap(); + unsafe { ptr::write_bytes(file_ptr.as_mut(), 0, file_size) }; + let file_slice = unsafe { slice::from_raw_parts_mut(file_ptr.as_mut(), file_size) }; file.read(file_slice).unwrap(); Some(file_slice) } /// Try to load a kernel from a TFTP boot server. -fn load_file_from_tftp_boot_server( - name: &str, - image: Handle, - st: &SystemTable, -) -> Option<&'static mut [u8]> { - let mut base_code_raw = locate_and_open_protocol::(image, st)?; - let base_code = base_code_raw.deref_mut(); +fn load_file_from_tftp_boot_server(name: &str) -> Option<&'static mut [u8]> { + let mut base_code = unsafe { + boot::open_protocol::( + OpenProtocolParams { + handle: uefi::boot::image_handle(), + agent: uefi::boot::image_handle(), + controller: None, + }, + OpenProtocolAttributes::GetProtocol, + ) + } + .ok()?; // Find the TFTP boot server. let mode = base_code.mode(); - assert!(mode.dhcp_ack_received); - let dhcpv4: &DhcpV4Packet = mode.dhcp_ack.as_ref(); - let server_ip = IpAddress::new_v4(dhcpv4.bootp_si_addr); + assert!(mode.dhcp_ack_received()); + let dhcpv4: &DhcpV4Packet = mode.dhcp_ack().as_ref(); + let server_ip = Ipv4Addr::from_octets(dhcpv4.bootp_si_addr); assert!(name.len() < 256); let filename = CStr8::from_bytes_with_nul(name.as_bytes()).unwrap(); // Determine the kernel file size. - let file_size = base_code.tftp_get_file_size(&server_ip, filename).ok()?; + let file_size = base_code + .tftp_get_file_size(&server_ip.into(), filename) + .ok()?; let kernel_size = usize::try_from(file_size).expect("The file size should fit into usize"); // Allocate some memory for the kernel file. - let ptr = st - .boot_services() - .allocate_pages( - AllocateType::AnyPages, - MemoryType::LOADER_DATA, - ((kernel_size - 1) / 4096) + 1, - ) - .expect("Failed to allocate memory for the file") as *mut u8; - let slice = unsafe { slice::from_raw_parts_mut(ptr, kernel_size) }; + let mut ptr = boot::allocate_pages( + AllocateType::AnyPages, + MemoryType::LOADER_DATA, + ((kernel_size - 1) / 4096) + 1, + ) + .expect("Failed to allocate memory for the file"); + let slice = unsafe { slice::from_raw_parts_mut(ptr.as_mut(), kernel_size) }; // Load the kernel file. base_code - .tftp_read_file(&server_ip, filename, Some(slice)) + .tftp_read_file(&server_ip.into(), filename, Some(slice)) .expect("Failed to read kernel file from the TFTP boot server"); Some(slice) @@ -460,27 +338,18 @@ fn create_page_tables( } } -fn init_logger( - image_handle: Handle, - st: &SystemTable, - config: &BootConfig, -) -> Option { - let gop_handle = st - .boot_services() - .get_handle_for_protocol::() - .ok()?; +fn init_logger(config: &BootConfig) -> Option { let mut gop = unsafe { - st.boot_services() - .open_protocol::( - OpenProtocolParams { - handle: gop_handle, - agent: image_handle, - controller: None, - }, - OpenProtocolAttributes::Exclusive, - ) - .ok()? - }; + boot::open_protocol::( + OpenProtocolParams { + handle: uefi::boot::image_handle(), + agent: uefi::boot::image_handle(), + controller: None, + }, + OpenProtocolAttributes::GetProtocol, + ) + } + .ok()?; let mode = { let modes = gop.modes(); @@ -548,10 +417,10 @@ fn panic(info: &core::panic::PanicInfo) -> ! { use core::arch::asm; use core::fmt::Write; - if let Some(st) = unsafe { &mut *SYSTEM_TABLE.get() } { - let _ = st.stdout().clear(); - let _ = writeln!(st.stdout(), "{}", info); - } + uefi::system::with_stdout(|stdout| { + let _ = stdout.clear(); + let _ = writeln!(stdout, "{}", info); + }); unsafe { bootloader_x86_64_common::logger::LOGGER diff --git a/uefi/src/memory_descriptor.rs b/uefi/src/memory_descriptor.rs index dcf05a9c..7dfb859e 100644 --- a/uefi/src/memory_descriptor.rs +++ b/uefi/src/memory_descriptor.rs @@ -1,6 +1,6 @@ use bootloader_api::info::MemoryRegionKind; use bootloader_x86_64_common::legacy_memory_region::LegacyMemoryRegion; -use uefi::table::boot::{MemoryDescriptor, MemoryType}; +use uefi::boot::{MemoryDescriptor, MemoryType}; use x86_64::PhysAddr; #[derive(Debug, Copy, Clone)]