From e890c28a1b94612f98b8443fd0ca75c3e36efaa8 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 29 Jun 2025 15:31:14 +0800 Subject: [PATCH 1/9] framework_uefi: Update uefi to 0.35 Testing: - [x] Can get arguments from shell and script Signed-off-by: Daniel Schaefer --- Cargo.lock | 76 ++++++++++++++++++++++++++++++++++---- framework_uefi/Cargo.toml | 3 +- framework_uefi/src/main.rs | 9 ++--- 3 files changed, 74 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eff80f59..62925294 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,7 +427,7 @@ dependencies = [ "sha2", "smbios-lib", "spin 0.10.0", - "uefi", + "uefi 0.20.0", "uefi-services", "windows", "windows-version", @@ -452,8 +452,7 @@ version = "0.5.0" dependencies = [ "framework_lib", "log", - "uefi", - "uefi-services", + "uefi 0.35.0", ] [[package]] @@ -1154,7 +1153,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcada80daa06c42ed5f48c9a043865edea5dc44cbf9ac009fda3b89526e28607" dependencies = [ - "ptr_meta_derive", + "ptr_meta_derive 0.2.0", +] + +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive 0.3.1", ] [[package]] @@ -1168,6 +1176,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "quote" version = "1.0.43" @@ -1539,9 +1558,25 @@ dependencies = [ "bitflags 1.3.2", "derive_more", "log", - "ptr_meta", + "ptr_meta 0.2.0", "ucs2", - "uefi-macros", + "uefi-macros 0.11.0", +] + +[[package]] +name = "uefi" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7569ceafb898907ff764629bac90ac24ba4203c38c33ef79ee88c74aa35b11" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "log", + "ptr_meta 0.3.1", + "ucs2", + "uefi-macros 0.18.1", + "uefi-raw", + "uguid", ] [[package]] @@ -1555,6 +1590,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "uefi-macros" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3dad47b3af8f99116c0f6d4d669c439487d9aaf1c8d9480d686cda6f3a8aa23" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "uefi-raw" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cad96b8baaf1615d3fdd0f03d04a0b487d857c1b51b19dcbfe05e2e3c447b78" +dependencies = [ + "bitflags 2.10.0", + "uguid", +] + [[package]] name = "uefi-services" version = "0.17.0" @@ -1562,9 +1618,15 @@ source = "git+https://github.com/FrameworkComputer/uefi-rs?branch=merged#95165e1 dependencies = [ "cfg-if", "log", - "uefi", + "uefi 0.20.0", ] +[[package]] +name = "uguid" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab14ea9660d240e7865ce9d54ecdbd1cd9fa5802ae6f4512f093c7907e921533" + [[package]] name = "unicode-ident" version = "1.0.22" diff --git a/framework_uefi/Cargo.toml b/framework_uefi/Cargo.toml index e984b1f5..1edf9163 100644 --- a/framework_uefi/Cargo.toml +++ b/framework_uefi/Cargo.toml @@ -19,8 +19,7 @@ default = [ ] readonly = [ "framework_lib/readonly" ] [dependencies] -uefi = { version = "0.20", features = ["alloc"] } -uefi-services = "0.17" +uefi = { version = "0.35", features = ["alloc"] } log = { version = "0.4", default-features = true } [dependencies.framework_lib] diff --git a/framework_uefi/src/main.rs b/framework_uefi/src/main.rs index caeeee2e..a9e8f581 100644 --- a/framework_uefi/src/main.rs +++ b/framework_uefi/src/main.rs @@ -5,18 +5,17 @@ use log::{debug, error, info, trace}; use uefi::prelude::*; #[allow(unused_imports)] -use uefi_services::{print, println}; +use uefi::{print, println}; extern crate alloc; use framework_lib::commandline; #[entry] -fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { - uefi_services::init(&mut system_table).unwrap(); - let bs = system_table.boot_services(); +fn main() -> Status { + uefi::helpers::init().unwrap(); - let args = commandline::uefi::get_args(bs, image_handle); + let args = commandline::uefi::get_args(); let args = commandline::parse(&args); if commandline::run_with_args(&args, false) == 0 { return Status::SUCCESS; From d26f77c06e847df6ed5103d53d621bae4c31bda7 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 29 Jun 2025 15:33:09 +0800 Subject: [PATCH 2/9] framework_lib: Rename uefi to fwk_uefi Avoid clash with uefi crate Signed-off-by: Daniel Schaefer --- framework_lib/src/capsule.rs | 2 +- framework_lib/src/chromium_ec/mod.rs | 2 +- framework_lib/src/commandline/mod.rs | 20 ++++++++++---------- framework_lib/src/lib.rs | 2 +- framework_lib/src/smbios.rs | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/framework_lib/src/capsule.rs b/framework_lib/src/capsule.rs index 8ded6493..d5eac38d 100644 --- a/framework_lib/src/capsule.rs +++ b/framework_lib/src/capsule.rs @@ -183,7 +183,7 @@ pub fn dump_winux_image(data: &[u8], header: &DisplayCapsule, filename: &str) { } #[cfg(feature = "uefi")] { - let ret = crate::uefi::fs::shell_write_file(filename, image); + let ret = crate::fw_uefi::fs::shell_write_file(filename, image); if let Err(err) = ret { println!("Failed to dump winux image: {:?}", err); } diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 87badf52..3935ca40 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -13,7 +13,7 @@ use crate::os_specific; use crate::power; use crate::smbios; #[cfg(feature = "uefi")] -use crate::uefi::shell_get_execution_break_flag; +use crate::fw_uefi::shell_get_execution_break_flag; use crate::util::{self, Platform}; use no_std_compat::time::Duration; diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 8f90d525..453d9421 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -63,7 +63,7 @@ use crate::touchpad::print_touchpad_fw_ver; #[cfg(feature = "hidapi")] use crate::touchscreen; #[cfg(feature = "uefi")] -use crate::uefi::enable_page_break; +use crate::fw_uefi::enable_page_break; #[cfg(feature = "rusb")] use crate::usbhub::check_usbhub_version; use crate::util::{self, Config, Platform, PlatformFamily}; @@ -1022,7 +1022,7 @@ fn print_esrt() { fn flash_ec(ec: &CrosEc, ec_bin_path: &str, flash_type: EcFlashType, dry_run: bool) { #[cfg(feature = "uefi")] - let data = crate::uefi::fs::shell_read_file(ec_bin_path); + let data = crate::fw_uefi::fs::shell_read_file(ec_bin_path); #[cfg(not(feature = "uefi"))] let data: Option> = { match fs::read(ec_bin_path) { @@ -1057,7 +1057,7 @@ fn dump_ec_flash(ec: &CrosEc, dump_path: &str) { } #[cfg(feature = "uefi")] { - let ret = crate::uefi::fs::shell_write_file(dump_path, &flash_bin); + let ret = crate::fw_uefi::fs::shell_write_file(dump_path, &flash_bin); if ret.is_err() { println!("Failed to dump EC FW image."); } @@ -1122,7 +1122,7 @@ fn dump_dgpu_eeprom(ec: &CrosEc, dump_path: &str) { } #[cfg(feature = "uefi")] { - if let Err(err) = crate::uefi::fs::shell_write_file(dump_path, &flash_bin) { + if let Err(err) = crate::fw_uefi::fs::shell_write_file(dump_path, &flash_bin) { error!("Failed to dump EC FW image: {:?}", err); return; } @@ -1579,7 +1579,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { // raw_command(&args[1..]); } else if let Some(pd_bin_path) = &args.pd_bin { #[cfg(feature = "uefi")] - let data: Option> = crate::uefi::fs::shell_read_file(pd_bin_path); + let data: Option> = crate::fw_uefi::fs::shell_read_file(pd_bin_path); #[cfg(not(feature = "uefi"))] let data = match fs::read(pd_bin_path) { Ok(data) => Some(data), @@ -1598,7 +1598,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } } else if let Some(ec_bin_path) = &args.ec_bin { #[cfg(feature = "uefi")] - let data: Option> = crate::uefi::fs::shell_read_file(ec_bin_path); + let data: Option> = crate::fw_uefi::fs::shell_read_file(ec_bin_path); #[cfg(not(feature = "uefi"))] let data = match fs::read(ec_bin_path) { Ok(data) => Some(data), @@ -1617,7 +1617,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } } else if let Some(capsule_path) = &args.capsule { #[cfg(feature = "uefi")] - let data: Option> = crate::uefi::fs::shell_read_file(capsule_path); + let data: Option> = crate::fw_uefi::fs::shell_read_file(capsule_path); #[cfg(not(feature = "uefi"))] let data = match fs::read(capsule_path) { Ok(data) => Some(data), @@ -1646,7 +1646,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } } else if let Some(capsule_path) = &args.h2o_capsule { #[cfg(feature = "uefi")] - let data = crate::uefi::fs::shell_read_file(capsule_path); + let data = crate::fw_uefi::fs::shell_read_file(capsule_path); #[cfg(not(feature = "uefi"))] let data = match fs::read(capsule_path) { Ok(data) => Some(data), @@ -1699,7 +1699,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } else if let Some(hash_file) = &args.hash { println!("Hashing file: {}", hash_file); #[cfg(feature = "uefi")] - let data = crate::uefi::fs::shell_read_file(hash_file); + let data = crate::fw_uefi::fs::shell_read_file(hash_file); #[cfg(not(feature = "uefi"))] let data = match fs::read(hash_file) { Ok(data) => Some(data), @@ -1728,7 +1728,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { Some(PlatformFamily::Framework16) | None ) { #[cfg(feature = "uefi")] - let data: Option> = crate::uefi::fs::shell_read_file(gpu_descriptor_file); + let data: Option> = crate::fw_uefi::fs::shell_read_file(gpu_descriptor_file); #[cfg(not(feature = "uefi"))] let data = match fs::read(gpu_descriptor_file) { Ok(data) => Some(data), diff --git a/framework_lib/src/lib.rs b/framework_lib/src/lib.rs index 1e76e724..5abdc2c5 100644 --- a/framework_lib/src/lib.rs +++ b/framework_lib/src/lib.rs @@ -47,7 +47,7 @@ pub mod parade_retimer; pub mod power; pub mod smbios; #[cfg(feature = "uefi")] -pub mod uefi; +pub mod fw_uefi; mod util; pub mod built_info { diff --git a/framework_lib/src/smbios.rs b/framework_lib/src/smbios.rs index aaac1cf5..76ce335e 100644 --- a/framework_lib/src/smbios.rs +++ b/framework_lib/src/smbios.rs @@ -193,7 +193,7 @@ pub fn get_smbios() -> Option { #[cfg(feature = "uefi")] pub fn get_smbios() -> Option { trace!("get_smbios() uefi entry"); - let data = crate::uefi::smbios_data().unwrap(); + let data = crate::fw_uefi::smbios_data().unwrap(); let version = None; // TODO: Maybe add the version here let smbios = SMBiosData::from_vec_and_version(data, version); Some(smbios) From 69a50ab07addbf461e3bdecb2e35413c0ffa9266 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 29 Jun 2025 15:34:09 +0800 Subject: [PATCH 3/9] framework_lib: Update uefi to 0.35 Signed-off-by: Daniel Schaefer --- Cargo.lock | 139 ++++++++------------------------------- Cargo.toml | 4 -- framework_lib/Cargo.toml | 3 +- 3 files changed, 28 insertions(+), 118 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62925294..0f688972 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -205,7 +205,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -220,12 +220,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "core-foundation" version = "0.6.4" @@ -288,7 +282,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.114", + "syn", ] [[package]] @@ -299,20 +293,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.114", -] - -[[package]] -name = "derive_more" -version = "0.99.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.114", + "syn", ] [[package]] @@ -333,7 +314,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -427,8 +408,7 @@ dependencies = [ "sha2", "smbios-lib", "spin 0.10.0", - "uefi 0.20.0", - "uefi-services", + "uefi", "windows", "windows-version", "winreg", @@ -452,7 +432,7 @@ version = "0.5.0" dependencies = [ "framework_lib", "log", - "uefi 0.35.0", + "uefi", ] [[package]] @@ -511,7 +491,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -807,7 +787,7 @@ checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1007,7 +987,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1147,33 +1127,13 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "ptr_meta" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcada80daa06c42ed5f48c9a043865edea5dc44cbf9ac009fda3b89526e28607" -dependencies = [ - "ptr_meta_derive 0.2.0", -] - [[package]] name = "ptr_meta" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" dependencies = [ - "ptr_meta_derive 0.3.1", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca9224df2e20e7c5548aeb5f110a0f3b77ef05f8585139b7148b59056168ed2" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "ptr_meta_derive", ] [[package]] @@ -1184,7 +1144,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1304,7 +1264,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1413,17 +1373,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[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.114" @@ -1443,7 +1392,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1472,7 +1421,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1483,7 +1432,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1550,19 +1499,6 @@ dependencies = [ "bit_field", ] -[[package]] -name = "uefi" -version = "0.20.0" -source = "git+https://github.com/FrameworkComputer/uefi-rs?branch=merged#95165e1adde99da7a460320538d908af8b55f87f" -dependencies = [ - "bitflags 1.3.2", - "derive_more", - "log", - "ptr_meta 0.2.0", - "ucs2", - "uefi-macros 0.11.0", -] - [[package]] name = "uefi" version = "0.35.0" @@ -1572,24 +1508,13 @@ dependencies = [ "bitflags 2.10.0", "cfg-if", "log", - "ptr_meta 0.3.1", + "ptr_meta", "ucs2", - "uefi-macros 0.18.1", + "uefi-macros", "uefi-raw", "uguid", ] -[[package]] -name = "uefi-macros" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0caeb0e7b31b9f1f347e541106be10aa8c66c76fa722a3298a4cd21433fabd4" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "uefi-macros" version = "0.18.1" @@ -1598,7 +1523,7 @@ checksum = "b3dad47b3af8f99116c0f6d4d669c439487d9aaf1c8d9480d686cda6f3a8aa23" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1611,16 +1536,6 @@ dependencies = [ "uguid", ] -[[package]] -name = "uefi-services" -version = "0.17.0" -source = "git+https://github.com/FrameworkComputer/uefi-rs?branch=merged#95165e1adde99da7a460320538d908af8b55f87f" -dependencies = [ - "cfg-if", - "log", - "uefi 0.20.0", -] - [[package]] name = "uguid" version = "2.2.0" @@ -1736,7 +1651,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn", "wasm-bindgen-shared", ] @@ -1824,7 +1739,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -1835,7 +1750,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -2094,7 +2009,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -2122,7 +2037,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", "synstructure", ] @@ -2143,7 +2058,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", "synstructure", ] @@ -2177,11 +2092,11 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] name = "zmij" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" +checksum = "94f63c051f4fe3c1509da62131a678643c5b6fbdc9273b2b79d4378ebda003d2" diff --git a/Cargo.toml b/Cargo.toml index d8108e1b..66801a46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,5 @@ default-members = [ "framework_tool", ] -[patch.crates-io] -uefi = { git = "https://github.com/FrameworkComputer/uefi-rs", branch = "merged" } -uefi-services = { git = "https://github.com/FrameworkComputer/uefi-rs", branch = "merged" } - [profile.release] lto = true diff --git a/framework_lib/Cargo.toml b/framework_lib/Cargo.toml index 0ec2e522..400415b8 100644 --- a/framework_lib/Cargo.toml +++ b/framework_lib/Cargo.toml @@ -37,8 +37,7 @@ rusb = { version = "0.9.4", optional = true } guid-create = { version = "0.5.0", default-features = false } [target.'cfg(target_os = "uefi")'.dependencies] -uefi = { version = "0.20", features = ["alloc"] } -uefi-services = "0.17" +uefi = { version = "0.35", features = ["alloc", "global_allocator", "panic_handler", "logger"] } plain = "0.2.3" redox_hwio = { git = "https://github.com/FrameworkComputer/rust-hwio", branch = "freebsd", default-features = false } smbios-lib = { git = "https://github.com/FrameworkComputer/smbios-lib.git", branch = "no-std", default-features = false } From 40aba421f45ba3665cb528d6826f29424e845774 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 29 Jun 2025 15:36:30 +0800 Subject: [PATCH 4/9] wip: update uefi Signed-off-by: Daniel Schaefer --- framework_lib/src/esrt/mod.rs | 29 ++++++++++++++--------------- framework_lib/src/lib.rs | 2 +- framework_lib/src/os_specific.rs | 10 +++++----- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/framework_lib/src/esrt/mod.rs b/framework_lib/src/esrt/mod.rs index 0ccc8a39..474f0865 100644 --- a/framework_lib/src/esrt/mod.rs +++ b/framework_lib/src/esrt/mod.rs @@ -38,6 +38,11 @@ use std::os::fd::AsRawFd; #[cfg(target_os = "freebsd")] use std::os::unix::fs::OpenOptionsExt; +#[cfg(feature = "uefi")] +use uefi::system::with_config_table; +#[cfg(feature = "uefi")] +use uefi::table::cfg::ConfigTableEntry; + pub const TGL_BIOS_GUID: GUID = GUID::build_from_components( 0xb3bdb2e4, 0xc5cb, @@ -511,22 +516,16 @@ pub const SYSTEM_RESOURCE_TABLE_GUID_BYTES: [u8; 16] = [ #[cfg(feature = "uefi")] pub fn get_esrt() -> Option { - let st = unsafe { uefi_services::system_table().as_ref() }; - let config_tables = st.config_table(); - - for table in config_tables { - // TODO: Why aren't they the same type? - //debug!("Table: {:?}", table); - let table_guid: CGuid = unsafe { std::mem::transmute(table.guid) }; - let table_guid = GUID::from(table_guid); - match table_guid { - SYSTEM_RESOURCE_TABLE_GUID => unsafe { - return esrt_from_buf(table.address as *const u8); - }, - _ => {} + with_config_table(|slice| { + for i in slice { + if i.guid == uefi::table::cfg::ESRT_GUID { + unsafe { + return esrt_from_buf(i.address as *const u8); + } + } } - } - None + None + }) } /// Parse the ESRT table buffer diff --git a/framework_lib/src/lib.rs b/framework_lib/src/lib.rs index 5abdc2c5..af236990 100644 --- a/framework_lib/src/lib.rs +++ b/framework_lib/src/lib.rs @@ -32,7 +32,7 @@ pub mod usbhub; #[cfg(feature = "uefi")] #[macro_use] -extern crate uefi_services; +extern crate uefi; pub mod capsule; pub mod capsule_content; diff --git a/framework_lib/src/os_specific.rs b/framework_lib/src/os_specific.rs index b77deb87..8a0ba170 100644 --- a/framework_lib/src/os_specific.rs +++ b/framework_lib/src/os_specific.rs @@ -1,7 +1,9 @@ //! Helper functions that need OS/platform specific implementations #[cfg(not(feature = "uefi"))] -use std::{thread, time}; +use std::thread; +#[cfg(not(feature = "uefi"))] +use core::time::Duration; #[cfg(feature = "uefi")] use alloc::string::{String, ToString}; @@ -40,15 +42,13 @@ pub fn get_os_version() -> String { pub fn sleep(micros: u64) { #[cfg(not(feature = "uefi"))] { - let duration = time::Duration::from_micros(micros); + let duration = Duration::from_micros(micros); thread::sleep(duration); } #[cfg(feature = "uefi")] { // TODO: It's not recommended to use this for sleep more than 10ms // Should use a one-shot timer event - let st = unsafe { uefi_services::system_table().as_ref() }; - let bs = st.boot_services(); - bs.stall(micros as usize); + uefi::boot::stall(micros as usize); } } From 3d6fc793797abb27a9ba8271a7550a86e5019191 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 29 Jun 2025 17:03:10 +0800 Subject: [PATCH 5/9] implement file system ops Signed-off-by: Daniel Schaefer --- Cargo.lock | 10 +- Cargo.toml | 5 + framework_lib/src/chromium_ec/mod.rs | 4 +- framework_lib/src/commandline/mod.rs | 4 +- framework_lib/src/commandline/uefi.rs | 25 ++-- framework_lib/src/esrt/mod.rs | 2 +- framework_lib/src/fw_uefi/fs.rs | 148 +++++++++++++++++++++ framework_lib/src/fw_uefi/mod.rs | 115 +++++++++++++++++ framework_lib/src/lib.rs | 4 +- framework_lib/src/os_specific.rs | 7 +- framework_lib/src/uefi/fs.rs | 132 ------------------- framework_lib/src/uefi/mod.rs | 179 -------------------------- 12 files changed, 297 insertions(+), 338 deletions(-) create mode 100644 framework_lib/src/fw_uefi/fs.rs create mode 100644 framework_lib/src/fw_uefi/mod.rs delete mode 100644 framework_lib/src/uefi/fs.rs delete mode 100644 framework_lib/src/uefi/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 0f688972..1b162f59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1502,8 +1502,7 @@ dependencies = [ [[package]] name = "uefi" version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da7569ceafb898907ff764629bac90ac24ba4203c38c33ef79ee88c74aa35b11" +source = "git+https://github.com/rust-osdev/uefi-rs?rev=1fcf4d84d5ed10fe76055469b6df01318eb35af8#1fcf4d84d5ed10fe76055469b6df01318eb35af8" dependencies = [ "bitflags 2.10.0", "cfg-if", @@ -1529,8 +1528,7 @@ dependencies = [ [[package]] name = "uefi-raw" version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cad96b8baaf1615d3fdd0f03d04a0b487d857c1b51b19dcbfe05e2e3c447b78" +source = "git+https://github.com/rust-osdev/uefi-rs?rev=1fcf4d84d5ed10fe76055469b6df01318eb35af8#1fcf4d84d5ed10fe76055469b6df01318eb35af8" dependencies = [ "bitflags 2.10.0", "uguid", @@ -1538,9 +1536,9 @@ dependencies = [ [[package]] name = "uguid" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab14ea9660d240e7865ce9d54ecdbd1cd9fa5802ae6f4512f093c7907e921533" +checksum = "0c8352f8c05e47892e7eaf13b34abd76a7f4aeaf817b716e88789381927f199c" [[package]] name = "unicode-ident" diff --git a/Cargo.toml b/Cargo.toml index 66801a46..f4dfcb51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,5 +19,10 @@ default-members = [ "framework_tool", ] +# Need latest commit that hasn't been released yet +[patch.crates-io] +uefi = { git = "https://github.com/rust-osdev/uefi-rs", rev = "1fcf4d84d5ed10fe76055469b6df01318eb35af8" } +uefi-raw = { git = "https://github.com/rust-osdev/uefi-rs", rev = "1fcf4d84d5ed10fe76055469b6df01318eb35af8" } + [profile.release] lto = true diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 3935ca40..94b8b93a 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -9,11 +9,11 @@ //! - `windows` - It uses [DHowett's Windows driver](https://github.com/DHowett/FrameworkWindowsUtils) use crate::ec_binary; +#[cfg(feature = "uefi")] +use crate::fw_uefi::shell_get_execution_break_flag; use crate::os_specific; use crate::power; use crate::smbios; -#[cfg(feature = "uefi")] -use crate::fw_uefi::shell_get_execution_break_flag; use crate::util::{self, Platform}; use no_std_compat::time::Duration; diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 453d9421..9e4dba72 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -48,6 +48,8 @@ use crate::chromium_ec::{EcError, EcResult}; use crate::csme; use crate::ec_binary; use crate::esrt; +#[cfg(feature = "uefi")] +use crate::fw_uefi::enable_page_break; #[cfg(feature = "rusb")] use crate::inputmodule::check_inputmodule_version; #[cfg(target_os = "linux")] @@ -62,8 +64,6 @@ use crate::smbios::{dmidecode_string_val, get_smbios, is_framework}; use crate::touchpad::print_touchpad_fw_ver; #[cfg(feature = "hidapi")] use crate::touchscreen; -#[cfg(feature = "uefi")] -use crate::fw_uefi::enable_page_break; #[cfg(feature = "rusb")] use crate::usbhub::check_usbhub_version; use crate::util::{self, Config, Platform, PlatformFamily}; diff --git a/framework_lib/src/commandline/uefi.rs b/framework_lib/src/commandline/uefi.rs index 58490c71..19a8c019 100644 --- a/framework_lib/src/commandline/uefi.rs +++ b/framework_lib/src/commandline/uefi.rs @@ -4,9 +4,8 @@ use alloc::vec::Vec; #[allow(unused_imports)] use log::{debug, error, info, trace}; -use uefi::prelude::BootServices; -use uefi::proto::shell_params::*; -use uefi::Handle; +use uefi::boot; +use uefi::proto::shell_params::ShellParameters; use crate::chromium_ec::commands::SetGpuSerialMagic; use crate::chromium_ec::{CrosEcDriverType, HardwareDeviceType}; @@ -15,13 +14,19 @@ use crate::commandline::{Cli, LogLevel}; use super::{ConsoleArg, FpBrightnessArg, InputDeckModeArg, RebootEcArg, TabletModeArg}; /// Get commandline arguments from UEFI environment -pub fn get_args(bs: &BootServices, image_handle: Handle) -> Vec { - if let Ok(shell_params) = bs.open_protocol_exclusive::(image_handle) { - shell_params.get_args() - } else { - // No protocol found if the application wasn't executed by the shell - vec![] - } +pub fn get_args() -> Vec { + let shell_params = uefi::boot::open_protocol_exclusive::(boot::image_handle()); + let shell_params = match shell_params { + Ok(s) => s, + Err(e) => { + error!("Failed to get ShellParameters protocol"); + // TODO: Return result + // return e.status(); + return vec![]; + } + }; + let args: Vec = shell_params.args().map(|x| x.to_string()).collect(); + args } pub fn parse(args: &[String]) -> Cli { diff --git a/framework_lib/src/esrt/mod.rs b/framework_lib/src/esrt/mod.rs index 474f0865..f39f49e5 100644 --- a/framework_lib/src/esrt/mod.rs +++ b/framework_lib/src/esrt/mod.rs @@ -518,7 +518,7 @@ pub const SYSTEM_RESOURCE_TABLE_GUID_BYTES: [u8; 16] = [ pub fn get_esrt() -> Option { with_config_table(|slice| { for i in slice { - if i.guid == uefi::table::cfg::ESRT_GUID { + if i.guid == ConfigTableEntry::ESRT_GUID { unsafe { return esrt_from_buf(i.address as *const u8); } diff --git a/framework_lib/src/fw_uefi/fs.rs b/framework_lib/src/fw_uefi/fs.rs new file mode 100644 index 00000000..e298fdcf --- /dev/null +++ b/framework_lib/src/fw_uefi/fs.rs @@ -0,0 +1,148 @@ +use alloc::vec; +use alloc::vec::Vec; +use uefi::prelude::*; +use uefi::proto::shell::{Shell, ShellProtocol}; +//use uefi::proto::shell::FileOpenMode; +use core::ffi::c_void; +use core::mem::MaybeUninit; +use core::ptr::NonNull; +use uefi::Result; + +#[repr(transparent)] +#[derive(Clone, Copy, Debug)] +pub struct ShellFileHandle(NonNull); + +const FILE_MODE_READ: u64 = 0x0000000000000001; +const FILE_MODE_WRITE: u64 = 0x0000000000000002; +const FILE_MODE_CREATE: u64 = 0x8000000000000000; + +pub fn wstr(string: &str) -> Vec { + let mut wstring = vec![]; + + for c in string.chars() { + wstring.push(c as u16); + } + wstring.push(0); + + wstring +} + +pub fn shell_read_file(path: &str) -> Option> { + let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); + let mut shell = + boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); + let shell = unsafe { + let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); + proto + }; + + println!("Opened shell protocol"); + + debug_assert_eq!(shell.major_version, 2); + debug_assert_eq!(shell.minor_version, 2); + + println!( + "Shell protocol ver: {}.{}", + shell.major_version, shell.minor_version + ); + + unsafe { + let c_path = wstr(path); + let mut mode = FILE_MODE_READ; + let mut handle: MaybeUninit<*const c_void> = MaybeUninit::zeroed(); + (shell.open_file_by_name)(c_path.as_ptr(), handle.as_mut_ptr().cast(), mode); + + println!("Opened file"); + + let file_handle = handle.assume_init(); + + let mut file_size = 0; + println!("get_file_size"); + let res = (shell.get_file_size)(file_handle, &mut file_size); + // let file_size = res.unwrap(); + + let mut buffer: Vec = vec![0; file_size as usize]; + let mut read_size = file_size as usize; + println!("read_file {} bytes", file_size); + (shell.read_file)( + file_handle, + &mut read_size, + buffer.as_mut_ptr() as *mut c_void, + ); + + println!("close_file"); + + // TODO: Make it auto-close using Rust destructors + (shell.close_file)(file_handle); + + println!("Done"); + + Some(buffer) + } +} + +pub fn shell_write_file(path: &str, data: &[u8]) -> Result { + let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); + let mut shell = + boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); + let shell = unsafe { + let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); + proto + }; + + debug_assert_eq!(shell.major_version, 2); + debug_assert_eq!(shell.minor_version, 2); + + unsafe { + // let mode = FileOpenMode::Read as u64 + FileOpenMode::Write as u64 + FileOpenMode::Create as u64; + let mode = FILE_MODE_READ + FILE_MODE_WRITE + FILE_MODE_CREATE; + let c_path = wstr(path); + let mut handle: MaybeUninit<*const c_void> = MaybeUninit::zeroed(); + (shell.open_file_by_name)(c_path.as_ptr(), handle.as_mut_ptr().cast(), mode); + let file_handle = handle.assume_init(); + + //// TODO: Free file_info buffer + //let file_info = (shell.0.GetFileInfo)(file_handle); + //if file_info.is_null() { + // println!("Failed to get file info"); + // return ret; + //} + + //// Not sure if it's useful to set FileInfo + ////let mut file_info = unsafe { + //// &mut *(file_info as *mut FileInfo) + ////}; + ////println!("file_info.Size: {}", file_info.Size); + + ////if file_info.Size != 0 { + //// file_info.Size = 0; + //// let ret = (shell.0.SetFileInfo)(file_handle, file_info); + //// if ret.0 != 0 { + //// println!("Failed to set file info"); + //// return ret; + //// } + ////} + + //let mut buffer_size = data.len() as usize; + //let ret = (shell.0.WriteFile)(file_handle, &mut buffer_size, data.as_ptr()); + //if ret.0 != 0 { + // println!("Failed to write file"); + // return ret; + //} + //if buffer_size != data.len() { + // println!( + // "Failed to write whole buffer. Instead of {} wrote {} bytes.", + // data.len(), + // buffer_size + // ); + // return Status(1); + //} + + let mut read_size = data.len(); + (shell.write_file)(file_handle, &mut read_size, data.as_ptr() as *mut c_void); + + (shell.close_file)(file_handle); + + Status::SUCCESS.to_result() + } +} diff --git a/framework_lib/src/fw_uefi/mod.rs b/framework_lib/src/fw_uefi/mod.rs new file mode 100644 index 00000000..e069a3b9 --- /dev/null +++ b/framework_lib/src/fw_uefi/mod.rs @@ -0,0 +1,115 @@ +use alloc::vec::Vec; +use core::slice; +use uefi::system::with_config_table; +use uefi::table::cfg::ConfigTableEntry; + +#[allow(unused_imports)] +use log::{debug, error, info, trace}; +use uefi::boot; +use uefi::proto::shell::{Shell, ShellProtocol}; + +pub mod fs; + +/// Returns true when the execution break was requested, false otherwise +pub fn shell_get_execution_break_flag() -> bool { + let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); + let shell = + boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); + unsafe { + let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); + (proto.get_page_break)() + } +} + +/// Enable pagination in UEFI shell +/// +/// Pagination is handled by the UEFI shell environment automatically, whenever +/// the application prints more than fits on the screen. +pub fn enable_page_break() { + let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); + let shell = + boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); + unsafe { + let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); + (proto.enable_page_break)() + } +} + +#[repr(C, packed)] +pub struct Smbios { + pub anchor: [u8; 4], + pub checksum: u8, + pub length: u8, + pub major_version: u8, + pub minor_version: u8, + pub max_structure_size: u16, + pub revision: u8, + pub formatted: [u8; 5], + pub inter_anchor: [u8; 5], + pub inter_checksum: u8, + pub table_length: u16, + pub table_address: u32, + pub structure_count: u16, + pub bcd_revision: u8, +} + +impl Smbios { + pub fn checksum_valid(&self) -> bool { + let mut sum: u8 = self.anchor.iter().sum::(); + sum += self.checksum; + sum += self.length; + sum += self.major_version; + sum += self.minor_version; + sum += self.max_structure_size as u8; + sum += self.revision; + sum += self.formatted.iter().sum::(); + sum == 0 + } +} + +pub struct Smbios3 { + pub anchor: [u8; 5], + pub checksum: u8, + pub length: u8, + pub major_version: u8, + pub minor_version: u8, + pub docrev: u8, + pub revision: u8, + _reserved: u8, + pub table_length: u32, + pub table_address: u64, +} + +pub fn smbios_data() -> Option> { + with_config_table(|slice| { + for i in slice { + let table_data = match i.guid { + ConfigTableEntry::SMBIOS3_GUID => unsafe { + let smbios = &*(i.address as *const Smbios3); + debug!("SMBIOS3 valid: {:?}", smbios.anchor == *b"_SM3_"); + Some(slice::from_raw_parts( + smbios.table_address as *const u8, + smbios.table_length as usize, + )) + }, + ConfigTableEntry::SMBIOS_GUID => unsafe { + let smbios = &*(i.address as *const Smbios); + debug!("SMBIOS valid: {:?}", smbios.checksum_valid()); + Some(slice::from_raw_parts( + smbios.table_address as *const u8, + smbios.table_length as usize, + )) + }, + _ => None, + }; + + if let Some(data) = table_data { + // Return directly here because there is only ever the old config + // table or the new V3 config table. Never both. + return Some(data.to_vec()); + } + } + + None + }) +} diff --git a/framework_lib/src/lib.rs b/framework_lib/src/lib.rs index af236990..92764319 100644 --- a/framework_lib/src/lib.rs +++ b/framework_lib/src/lib.rs @@ -42,12 +42,12 @@ pub mod commandline; pub mod csme; pub mod ec_binary; pub mod esrt; +#[cfg(feature = "uefi")] +pub mod fw_uefi; mod os_specific; pub mod parade_retimer; pub mod power; pub mod smbios; -#[cfg(feature = "uefi")] -pub mod fw_uefi; mod util; pub mod built_info { diff --git a/framework_lib/src/os_specific.rs b/framework_lib/src/os_specific.rs index 8a0ba170..3566e4c8 100644 --- a/framework_lib/src/os_specific.rs +++ b/framework_lib/src/os_specific.rs @@ -1,9 +1,8 @@ //! Helper functions that need OS/platform specific implementations +use core::time::Duration; #[cfg(not(feature = "uefi"))] use std::thread; -#[cfg(not(feature = "uefi"))] -use core::time::Duration; #[cfg(feature = "uefi")] use alloc::string::{String, ToString}; @@ -40,15 +39,15 @@ pub fn get_os_version() -> String { /// Sleep a number of microseconds pub fn sleep(micros: u64) { + let duration = Duration::from_micros(micros); #[cfg(not(feature = "uefi"))] { - let duration = Duration::from_micros(micros); thread::sleep(duration); } #[cfg(feature = "uefi")] { // TODO: It's not recommended to use this for sleep more than 10ms // Should use a one-shot timer event - uefi::boot::stall(micros as usize); + uefi::boot::stall(duration); } } diff --git a/framework_lib/src/uefi/fs.rs b/framework_lib/src/uefi/fs.rs deleted file mode 100644 index a5e2ca96..00000000 --- a/framework_lib/src/uefi/fs.rs +++ /dev/null @@ -1,132 +0,0 @@ -use alloc::vec; -use alloc::vec::Vec; -use uefi::prelude::*; -use uefi::proto::shell::FileOpenMode; -use uefi::Result; - -use super::find_shell_handle; - -pub fn wstr(string: &str) -> Vec { - let mut wstring = vec![]; - - for c in string.chars() { - wstring.push(c as u16); - } - wstring.push(0); - - wstring -} - -pub fn shell_read_file(path: &str) -> Option> { - let shell = if let Some(shell) = find_shell_handle() { - shell - } else { - println!("Failed to open Shell Protocol"); - return None; - }; - - debug_assert_eq!(shell.major_version, 2); - debug_assert_eq!(shell.minor_version, 2); - - let c_path = wstr(path); - let handle = shell.open_file_by_name(c_path.as_slice(), FileOpenMode::Read as u64); - - let handle = if let Ok(handle) = handle { - handle - } else { - println!("Failed to open file: {:?}", handle); - return None; - }; - - let handle = if let Some(handle) = handle { - handle - } else { - println!("Failed to open file: {:?}", handle); - return None; - }; - let file_handle = handle; - - let res = shell.get_file_size(file_handle); - let file_size = res.unwrap(); - - let mut buffer: Vec = vec![0; file_size as usize]; - let res = shell.read_file(file_handle, &mut buffer); - res.unwrap(); - - // TODO: Make it auto-close using Rust destructors - shell.close_file(file_handle).unwrap(); - - Some(buffer) -} - -pub fn shell_write_file(path: &str, data: &[u8]) -> Result { - let shell = if let Some(shell) = find_shell_handle() { - shell - } else { - println!("Failed to open Shell Protocol"); - return Status::LOAD_ERROR.into(); - }; - - debug_assert_eq!(shell.major_version, 2); - debug_assert_eq!(shell.minor_version, 2); - - let mode = FileOpenMode::Read as u64 + FileOpenMode::Write as u64 + FileOpenMode::Create as u64; - let c_path = wstr(path); - let handle = shell.open_file_by_name(c_path.as_slice(), mode); - let handle = if let Ok(handle) = handle { - handle - } else { - println!("Failed to open file: {:?}", handle); - return Status::LOAD_ERROR.into(); - }; - let handle = if let Some(handle) = handle { - handle - } else { - println!("Failed to open file: {:?}", handle); - return Status::LOAD_ERROR.into(); - }; - let file_handle = handle; - - //// TODO: Free file_info buffer - //let file_info = (shell.0.GetFileInfo)(file_handle); - //if file_info.is_null() { - // println!("Failed to get file info"); - // return ret; - //} - - //// Not sure if it's useful to set FileInfo - ////let mut file_info = unsafe { - //// &mut *(file_info as *mut FileInfo) - ////}; - ////println!("file_info.Size: {}", file_info.Size); - - ////if file_info.Size != 0 { - //// file_info.Size = 0; - //// let ret = (shell.0.SetFileInfo)(file_handle, file_info); - //// if ret.0 != 0 { - //// println!("Failed to set file info"); - //// return ret; - //// } - ////} - - //let mut buffer_size = data.len() as usize; - //let ret = (shell.0.WriteFile)(file_handle, &mut buffer_size, data.as_ptr()); - //if ret.0 != 0 { - // println!("Failed to write file"); - // return ret; - //} - //if buffer_size != data.len() { - // println!( - // "Failed to write whole buffer. Instead of {} wrote {} bytes.", - // data.len(), - // buffer_size - // ); - // return Status(1); - //} - - shell.write_file(file_handle, data).unwrap(); - - shell.close_file(file_handle).unwrap(); - - Status::SUCCESS.into() -} diff --git a/framework_lib/src/uefi/mod.rs b/framework_lib/src/uefi/mod.rs deleted file mode 100644 index 71d85b44..00000000 --- a/framework_lib/src/uefi/mod.rs +++ /dev/null @@ -1,179 +0,0 @@ -use alloc::vec::Vec; -use core::slice; -use uefi::table::boot::{OpenProtocolAttributes, OpenProtocolParams, ScopedProtocol, SearchType}; - -#[allow(unused_imports)] -use log::{debug, error, info, trace}; -use uefi::proto::shell::Shell; -use uefi::table::cfg::{SMBIOS3_GUID, SMBIOS_GUID}; -use uefi::table::{Boot, SystemTable}; -use uefi::Identify; - -pub mod fs; - -pub fn get_system_table() -> &'static SystemTable { - unsafe { uefi_services::system_table().as_ref() } -} - -fn find_shell_handle() -> Option> { - let st = unsafe { uefi_services::system_table().as_ref() }; - let boot_services = st.boot_services(); - let shell_handles = boot_services.locate_handle_buffer(SearchType::ByProtocol(&Shell::GUID)); - if let Ok(sh_buf) = shell_handles { - for handle in &*sh_buf { - return Some(unsafe { - boot_services - .open_protocol::( - OpenProtocolParams { - handle: *handle, - agent: boot_services.image_handle(), - controller: None, - }, - OpenProtocolAttributes::GetProtocol, - ) - .expect("Failed to open Shell handle") - }); - } - } else { - panic!("No shell handle found!"); - } - None -} - -/// Returns true when the execution break was requested, false otherwise -pub fn shell_get_execution_break_flag() -> bool { - let st = unsafe { uefi_services::system_table().as_ref() }; - let boot_services = st.boot_services(); - let shell_handles = boot_services.locate_handle_buffer(SearchType::ByProtocol(&Shell::GUID)); - if let Ok(sh_buf) = shell_handles { - for handle in &*sh_buf { - let shell_handle = unsafe { - boot_services - .open_protocol::( - OpenProtocolParams { - handle: *handle, - agent: boot_services.image_handle(), - controller: None, - }, - OpenProtocolAttributes::GetProtocol, - ) - .expect("Failed to open Shell handle") - }; - - let event = unsafe { shell_handle.execution_break.unsafe_clone() }; - return boot_services.check_event(event).unwrap(); - } - return false; - } else { - panic!("No shell handle found!"); - } -} - -/// Enable pagination in UEFI shell -/// -/// Pagination is handled by the UEFI shell environment automatically, whenever -/// the application prints more than fits on the screen. -pub fn enable_page_break() { - let st = unsafe { uefi_services::system_table().as_ref() }; - let boot_services = st.boot_services(); - let shell_handles = boot_services.locate_handle_buffer(SearchType::ByProtocol(&Shell::GUID)); - if let Ok(sh_buf) = shell_handles { - for handle in &*sh_buf { - //trace!("Calling enable_page_break"); - let shell_handle = unsafe { - boot_services - .open_protocol::( - OpenProtocolParams { - handle: *handle, - agent: boot_services.image_handle(), - controller: None, - }, - OpenProtocolAttributes::GetProtocol, - ) - .expect("Failed to open Shell handle") - }; - shell_handle.enable_page_break(); - } - } else { - panic!("No shell handle found!"); - } -} - -#[repr(C, packed)] -pub struct Smbios { - pub anchor: [u8; 4], - pub checksum: u8, - pub length: u8, - pub major_version: u8, - pub minor_version: u8, - pub max_structure_size: u16, - pub revision: u8, - pub formatted: [u8; 5], - pub inter_anchor: [u8; 5], - pub inter_checksum: u8, - pub table_length: u16, - pub table_address: u32, - pub structure_count: u16, - pub bcd_revision: u8, -} - -impl Smbios { - pub fn checksum_valid(&self) -> bool { - let mut sum: u8 = self.anchor.iter().sum::(); - sum += self.checksum; - sum += self.length; - sum += self.major_version; - sum += self.minor_version; - sum += self.max_structure_size as u8; - sum += self.revision; - sum += self.formatted.iter().sum::(); - sum == 0 - } -} - -pub struct Smbios3 { - pub anchor: [u8; 5], - pub checksum: u8, - pub length: u8, - pub major_version: u8, - pub minor_version: u8, - pub docrev: u8, - pub revision: u8, - _reserved: u8, - pub table_length: u32, - pub table_address: u64, -} - -pub fn smbios_data() -> Option> { - let st = unsafe { uefi_services::system_table().as_ref() }; - let config_tables = st.config_table(); - - for table in config_tables { - let table_data = match table.guid { - SMBIOS3_GUID => unsafe { - let smbios = &*(table.address as *const Smbios3); - debug!("SMBIOS3 valid: {:?}", smbios.anchor == *b"_SM3_"); - Some(slice::from_raw_parts( - smbios.table_address as *const u8, - smbios.table_length as usize, - )) - }, - SMBIOS_GUID => unsafe { - let smbios = &*(table.address as *const Smbios); - debug!("SMBIOS valid: {:?}", smbios.checksum_valid()); - Some(slice::from_raw_parts( - smbios.table_address as *const u8, - smbios.table_length as usize, - )) - }, - _ => None, - }; - - if let Some(data) = table_data { - // Return directly here because there is only ever the old config - // table or the new V3 config table. Never both. - return Some(data.to_vec()); - } - } - None -} From c26d4a16073635a9e61d32ede6c6531d4952546a Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 18 Jan 2026 15:54:28 +0800 Subject: [PATCH 6/9] update uefi to 0.36.1 Signed-off-by: Daniel Schaefer --- Cargo.lock | 15 +++++++++------ Cargo.toml | 5 ----- framework_lib/Cargo.toml | 3 ++- framework_lib/src/fw_uefi/fs.rs | 3 ++- framework_lib/src/fw_uefi/mod.rs | 5 +++-- framework_uefi/Cargo.toml | 2 +- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b162f59..5239a7c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -409,6 +409,7 @@ dependencies = [ "smbios-lib", "spin 0.10.0", "uefi", + "uefi-raw", "windows", "windows-version", "winreg", @@ -1501,8 +1502,9 @@ dependencies = [ [[package]] name = "uefi" -version = "0.35.0" -source = "git+https://github.com/rust-osdev/uefi-rs?rev=1fcf4d84d5ed10fe76055469b6df01318eb35af8#1fcf4d84d5ed10fe76055469b6df01318eb35af8" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe9058b73ee2b6559524af9e33199c13b2485ddbf3ad1181b68051cdc50c17" dependencies = [ "bitflags 2.10.0", "cfg-if", @@ -1516,9 +1518,9 @@ dependencies = [ [[package]] name = "uefi-macros" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3dad47b3af8f99116c0f6d4d669c439487d9aaf1c8d9480d686cda6f3a8aa23" +checksum = "4687412b5ac74d245d5bfb1733ede50c31be19bf8a4b6a967a29b451bab49e67" dependencies = [ "proc-macro2", "quote", @@ -1527,8 +1529,9 @@ dependencies = [ [[package]] name = "uefi-raw" -version = "0.11.0" -source = "git+https://github.com/rust-osdev/uefi-rs?rev=1fcf4d84d5ed10fe76055469b6df01318eb35af8#1fcf4d84d5ed10fe76055469b6df01318eb35af8" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f64fe59e11af447d12fd60a403c74106eb104309f34b4c6dbce6e927d97da9d" dependencies = [ "bitflags 2.10.0", "uguid", diff --git a/Cargo.toml b/Cargo.toml index f4dfcb51..66801a46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,5 @@ default-members = [ "framework_tool", ] -# Need latest commit that hasn't been released yet -[patch.crates-io] -uefi = { git = "https://github.com/rust-osdev/uefi-rs", rev = "1fcf4d84d5ed10fe76055469b6df01318eb35af8" } -uefi-raw = { git = "https://github.com/rust-osdev/uefi-rs", rev = "1fcf4d84d5ed10fe76055469b6df01318eb35af8" } - [profile.release] lto = true diff --git a/framework_lib/Cargo.toml b/framework_lib/Cargo.toml index 400415b8..46286c71 100644 --- a/framework_lib/Cargo.toml +++ b/framework_lib/Cargo.toml @@ -37,7 +37,8 @@ rusb = { version = "0.9.4", optional = true } guid-create = { version = "0.5.0", default-features = false } [target.'cfg(target_os = "uefi")'.dependencies] -uefi = { version = "0.35", features = ["alloc", "global_allocator", "panic_handler", "logger"] } +uefi = { version = "0.36.1", features = ["alloc", "global_allocator", "panic_handler", "logger"] } +uefi-raw = "0.13" plain = "0.2.3" redox_hwio = { git = "https://github.com/FrameworkComputer/rust-hwio", branch = "freebsd", default-features = false } smbios-lib = { git = "https://github.com/FrameworkComputer/smbios-lib.git", branch = "no-std", default-features = false } diff --git a/framework_lib/src/fw_uefi/fs.rs b/framework_lib/src/fw_uefi/fs.rs index e298fdcf..7b397c54 100644 --- a/framework_lib/src/fw_uefi/fs.rs +++ b/framework_lib/src/fw_uefi/fs.rs @@ -1,7 +1,8 @@ use alloc::vec; use alloc::vec::Vec; use uefi::prelude::*; -use uefi::proto::shell::{Shell, ShellProtocol}; +use uefi::proto::shell::Shell; +use uefi_raw::protocol::shell::ShellProtocol; //use uefi::proto::shell::FileOpenMode; use core::ffi::c_void; use core::mem::MaybeUninit; diff --git a/framework_lib/src/fw_uefi/mod.rs b/framework_lib/src/fw_uefi/mod.rs index e069a3b9..7b70608e 100644 --- a/framework_lib/src/fw_uefi/mod.rs +++ b/framework_lib/src/fw_uefi/mod.rs @@ -6,7 +6,8 @@ use uefi::table::cfg::ConfigTableEntry; #[allow(unused_imports)] use log::{debug, error, info, trace}; use uefi::boot; -use uefi::proto::shell::{Shell, ShellProtocol}; +use uefi::proto::shell::Shell; +use uefi_raw::protocol::shell::ShellProtocol; pub mod fs; @@ -17,7 +18,7 @@ pub fn shell_get_execution_break_flag() -> bool { boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); unsafe { let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); - (proto.get_page_break)() + (proto.get_page_break)().into() } } diff --git a/framework_uefi/Cargo.toml b/framework_uefi/Cargo.toml index 1edf9163..0b3f2ec0 100644 --- a/framework_uefi/Cargo.toml +++ b/framework_uefi/Cargo.toml @@ -19,7 +19,7 @@ default = [ ] readonly = [ "framework_lib/readonly" ] [dependencies] -uefi = { version = "0.35", features = ["alloc"] } +uefi = { version = "0.36.1", features = ["alloc"] } log = { version = "0.4", default-features = true } [dependencies.framework_lib] From ff6f1246f6a83be71b6c8d740e77ebe1d8cabbce Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 18 Jan 2026 16:17:57 +0800 Subject: [PATCH 7/9] simplify fs by using uefi-rs definitions Signed-off-by: Daniel Schaefer --- framework_lib/src/fw_uefi/fs.rs | 171 +++++++++++--------------------- 1 file changed, 58 insertions(+), 113 deletions(-) diff --git a/framework_lib/src/fw_uefi/fs.rs b/framework_lib/src/fw_uefi/fs.rs index 7b397c54..83c2d960 100644 --- a/framework_lib/src/fw_uefi/fs.rs +++ b/framework_lib/src/fw_uefi/fs.rs @@ -1,149 +1,94 @@ use alloc::vec; use alloc::vec::Vec; -use uefi::prelude::*; +use core::mem::MaybeUninit; +use uefi::boot; use uefi::proto::shell::Shell; +use uefi::{CString16, Result, Status, StatusExt}; +use uefi_raw::protocol::file_system::FileMode; use uefi_raw::protocol::shell::ShellProtocol; -//use uefi::proto::shell::FileOpenMode; -use core::ffi::c_void; -use core::mem::MaybeUninit; -use core::ptr::NonNull; -use uefi::Result; - -#[repr(transparent)] -#[derive(Clone, Copy, Debug)] -pub struct ShellFileHandle(NonNull); - -const FILE_MODE_READ: u64 = 0x0000000000000001; -const FILE_MODE_WRITE: u64 = 0x0000000000000002; -const FILE_MODE_CREATE: u64 = 0x8000000000000000; +use uefi_raw::protocol::shell_params::ShellFileHandle; -pub fn wstr(string: &str) -> Vec { - let mut wstring = vec![]; - - for c in string.chars() { - wstring.push(c as u16); - } - wstring.push(0); - - wstring -} - -pub fn shell_read_file(path: &str) -> Option> { +fn get_shell_protocol() -> &'static ShellProtocol { let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); - let mut shell = + let shell = boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); - let shell = unsafe { - let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); + // SAFETY: The Shell wrapper contains the raw ShellProtocol + unsafe { + let proto: &ShellProtocol = core::mem::transmute(shell.get().unwrap()); + // Leak to get 'static lifetime - protocol stays valid while shell is running + core::mem::forget(shell); proto - }; - - println!("Opened shell protocol"); - - debug_assert_eq!(shell.major_version, 2); - debug_assert_eq!(shell.minor_version, 2); + } +} - println!( - "Shell protocol ver: {}.{}", - shell.major_version, shell.minor_version - ); +pub fn shell_read_file(path: &str) -> Option> { + let shell = get_shell_protocol(); + let c_path = CString16::try_from(path).ok()?; unsafe { - let c_path = wstr(path); - let mut mode = FILE_MODE_READ; - let mut handle: MaybeUninit<*const c_void> = MaybeUninit::zeroed(); - (shell.open_file_by_name)(c_path.as_ptr(), handle.as_mut_ptr().cast(), mode); - - println!("Opened file"); + let mut handle: MaybeUninit = MaybeUninit::zeroed(); + let status = (shell.open_file_by_name)( + c_path.as_ptr().cast(), + handle.as_mut_ptr(), + FileMode::READ.bits(), + ); + if status.is_error() { + return None; + } let file_handle = handle.assume_init(); - let mut file_size = 0; - println!("get_file_size"); - let res = (shell.get_file_size)(file_handle, &mut file_size); - // let file_size = res.unwrap(); + let mut file_size: u64 = 0; + let status = (shell.get_file_size)(file_handle, &mut file_size); + if status.is_error() { + let _ = (shell.close_file)(file_handle); + return None; + } let mut buffer: Vec = vec![0; file_size as usize]; let mut read_size = file_size as usize; - println!("read_file {} bytes", file_size); - (shell.read_file)( + let status = (shell.read_file)( file_handle, &mut read_size, - buffer.as_mut_ptr() as *mut c_void, + buffer.as_mut_ptr().cast(), ); - println!("close_file"); - - // TODO: Make it auto-close using Rust destructors - (shell.close_file)(file_handle); + let _ = (shell.close_file)(file_handle); - println!("Done"); + if status.is_error() { + return None; + } + buffer.truncate(read_size); Some(buffer) } } pub fn shell_write_file(path: &str, data: &[u8]) -> Result { - let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); - let mut shell = - boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); - let shell = unsafe { - let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); - proto - }; - - debug_assert_eq!(shell.major_version, 2); - debug_assert_eq!(shell.minor_version, 2); + let shell = get_shell_protocol(); + let c_path = CString16::try_from(path).map_err(|_| uefi::Error::from(Status::INVALID_PARAMETER))?; unsafe { - // let mode = FileOpenMode::Read as u64 + FileOpenMode::Write as u64 + FileOpenMode::Create as u64; - let mode = FILE_MODE_READ + FILE_MODE_WRITE + FILE_MODE_CREATE; - let c_path = wstr(path); - let mut handle: MaybeUninit<*const c_void> = MaybeUninit::zeroed(); - (shell.open_file_by_name)(c_path.as_ptr(), handle.as_mut_ptr().cast(), mode); - let file_handle = handle.assume_init(); - - //// TODO: Free file_info buffer - //let file_info = (shell.0.GetFileInfo)(file_handle); - //if file_info.is_null() { - // println!("Failed to get file info"); - // return ret; - //} - - //// Not sure if it's useful to set FileInfo - ////let mut file_info = unsafe { - //// &mut *(file_info as *mut FileInfo) - ////}; - ////println!("file_info.Size: {}", file_info.Size); - - ////if file_info.Size != 0 { - //// file_info.Size = 0; - //// let ret = (shell.0.SetFileInfo)(file_handle, file_info); - //// if ret.0 != 0 { - //// println!("Failed to set file info"); - //// return ret; - //// } - ////} + let mode = FileMode::READ | FileMode::WRITE | FileMode::CREATE; + let mut handle: MaybeUninit = MaybeUninit::zeroed(); + (shell.open_file_by_name)( + c_path.as_ptr().cast(), + handle.as_mut_ptr(), + mode.bits(), + ) + .to_result()?; - //let mut buffer_size = data.len() as usize; - //let ret = (shell.0.WriteFile)(file_handle, &mut buffer_size, data.as_ptr()); - //if ret.0 != 0 { - // println!("Failed to write file"); - // return ret; - //} - //if buffer_size != data.len() { - // println!( - // "Failed to write whole buffer. Instead of {} wrote {} bytes.", - // data.len(), - // buffer_size - // ); - // return Status(1); - //} + let file_handle = handle.assume_init(); - let mut read_size = data.len(); - (shell.write_file)(file_handle, &mut read_size, data.as_ptr() as *mut c_void); + let mut write_size = data.len(); + let status = (shell.write_file)( + file_handle, + &mut write_size, + data.as_ptr() as *mut _, + ); - (shell.close_file)(file_handle); + let _ = (shell.close_file)(file_handle); - Status::SUCCESS.to_result() + status.to_result() } } From 43791d45dcac11d0fab190f5f36e78dd6c98dc8c Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 25 Jan 2026 15:01:55 +0800 Subject: [PATCH 8/9] test uefi program to avoid regressions Signed-off-by: Daniel Schaefer --- .github/workflows/ci.yml | 19 +++++++ .gitignore | 3 ++ framework_lib/src/fw_uefi/fs.rs | 18 +++++-- framework_lib/src/fw_uefi/mod.rs | 43 ++++++++++------ framework_uefi/Makefile | 79 +++++++++++++++++++++++++++-- framework_uefi/tests/test.nsh | 82 +++++++++++++++++++++++++++++++ framework_uefi/winux.bin | Bin 0 -> 676898 bytes 7 files changed, 222 insertions(+), 22 deletions(-) create mode 100644 framework_uefi/tests/test.nsh create mode 100644 framework_uefi/winux.bin diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a46fc070..abd44170 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,6 +106,25 @@ jobs: name: UEFI-Shell-fwk.iso path: framework_uefi/build/x86_64-unknown-uefi/UEFI-Shell-fwk.iso + test-uefi: + name: Test UEFI + runs-on: ubuntu-24.04 + env: + CARGO_NET_GIT_FETCH_WITH_CLI: true + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust toolchain + run: rustup show + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y mtools parted qemu-system-x86 + + - name: Run UEFI tests in QEMU + run: make -C framework_uefi test + build-windows: name: Build Windows runs-on: windows-2022 diff --git a/.gitignore b/.gitignore index 13b77fcd..a39b6179 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ result* # Claude Code tmpclaude* + +# UEFI test artifacts +dump.bmp diff --git a/framework_lib/src/fw_uefi/fs.rs b/framework_lib/src/fw_uefi/fs.rs index 83c2d960..b4399036 100644 --- a/framework_lib/src/fw_uefi/fs.rs +++ b/framework_lib/src/fw_uefi/fs.rs @@ -1,7 +1,7 @@ use alloc::vec; use alloc::vec::Vec; use core::mem::MaybeUninit; -use uefi::boot; +use uefi::boot::{self, OpenProtocolAttributes, OpenProtocolParams}; use uefi::proto::shell::Shell; use uefi::{CString16, Result, Status, StatusExt}; use uefi_raw::protocol::file_system::FileMode; @@ -10,8 +10,20 @@ use uefi_raw::protocol::shell_params::ShellFileHandle; fn get_shell_protocol() -> &'static ShellProtocol { let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); - let shell = - boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); + + // Use GetProtocol instead of Exclusive since we're running inside the shell + let shell = unsafe { + boot::open_protocol::( + OpenProtocolParams { + handle, + agent: boot::image_handle(), + controller: None, + }, + OpenProtocolAttributes::GetProtocol, + ) + .expect("Failed to open Shell protocol") + }; + // SAFETY: The Shell wrapper contains the raw ShellProtocol unsafe { let proto: &ShellProtocol = core::mem::transmute(shell.get().unwrap()); diff --git a/framework_lib/src/fw_uefi/mod.rs b/framework_lib/src/fw_uefi/mod.rs index 7b70608e..82f823a4 100644 --- a/framework_lib/src/fw_uefi/mod.rs +++ b/framework_lib/src/fw_uefi/mod.rs @@ -5,35 +5,50 @@ use uefi::table::cfg::ConfigTableEntry; #[allow(unused_imports)] use log::{debug, error, info, trace}; -use uefi::boot; +use uefi::boot::{self, OpenProtocolAttributes, OpenProtocolParams}; use uefi::proto::shell::Shell; use uefi_raw::protocol::shell::ShellProtocol; pub mod fs; -/// Returns true when the execution break was requested, false otherwise -pub fn shell_get_execution_break_flag() -> bool { +fn get_shell_protocol() -> &'static ShellProtocol { let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); - let shell = - boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); + + // Use GetProtocol instead of Exclusive since we're running inside the shell + let shell = unsafe { + boot::open_protocol::( + OpenProtocolParams { + handle, + agent: boot::image_handle(), + controller: None, + }, + OpenProtocolAttributes::GetProtocol, + ) + .expect("Failed to open Shell protocol") + }; + + // SAFETY: The Shell wrapper contains the raw ShellProtocol unsafe { - let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); - (proto.get_page_break)().into() + let proto: &ShellProtocol = core::mem::transmute(shell.get().unwrap()); + // Leak to get 'static lifetime - protocol stays valid while shell is running + core::mem::forget(shell); + proto } } +/// Returns true when the execution break was requested, false otherwise +pub fn shell_get_execution_break_flag() -> bool { + let shell = get_shell_protocol(); + unsafe { (shell.get_page_break)().into() } +} + /// Enable pagination in UEFI shell /// /// Pagination is handled by the UEFI shell environment automatically, whenever /// the application prints more than fits on the screen. pub fn enable_page_break() { - let handle = boot::get_handle_for_protocol::().expect("No Shell handles"); - let shell = - boot::open_protocol_exclusive::(handle).expect("Failed to open Shell protocol"); - unsafe { - let proto: &ShellProtocol = std::mem::transmute(shell.get().unwrap()); - (proto.enable_page_break)() - } + let shell = get_shell_protocol(); + unsafe { (shell.enable_page_break)() } } #[repr(C, packed)] diff --git a/framework_uefi/Makefile b/framework_uefi/Makefile index 0814ff42..418e29a0 100644 --- a/framework_uefi/Makefile +++ b/framework_uefi/Makefile @@ -5,14 +5,24 @@ FEATURES?='' SRC_DIR=. QEMU?=qemu-system-x86_64 +OVMF_CODE?=$(BUILD)/OVMF_CODE.fd +OVMF_VARS?=$(BUILD)/OVMF_VARS.fd + QEMU_FLAGS=\ -M q35 \ -m 1024 \ -net none \ -vga std \ - -bios /usr/share/OVMF/OVMF_CODE.fd + -drive if=pflash,format=raw,readonly=on,file=$(OVMF_CODE) \ + -drive if=pflash,format=raw,file=$(BUILD)/ovmf_vars.fd + +QEMU_TEST_FLAGS=\ + $(QEMU_FLAGS) \ + -display none \ + -serial file:$(BUILD)/serial.log \ + -no-reboot -.PHONY: qemu clean +.PHONY: qemu clean test test-qemu all: $(BUILD)/boot.img @@ -21,8 +31,8 @@ iso: $(BUILD)/UEFI-Shell-fwk.iso clean: rm -rf $(BUILD) -qemu: $(BUILD)/boot.img - $(QEMU) $(QEMU_FLAGS) $< +qemu: $(BUILD)/boot.img $(BUILD)/OVMF_CODE.fd $(BUILD)/ovmf_vars.fd + $(QEMU) $(QEMU_FLAGS) -drive format=raw,file=$< # Create ESP partition and filesystem $(BUILD)/boot.img: $(BUILD)/efi.img @@ -46,7 +56,14 @@ $(BUILD)/efi.img: $(BUILD)/boot.efi mv $@.tmp $@ $(BUILD)/shellx64.efi: - wget https://github.com/pbatard/UEFI-Shell/releases/download/24H2/shellx64.efi -O $@ + mkdir -p $(BUILD) + curl -L https://github.com/pbatard/UEFI-Shell/releases/download/24H2/shellx64.efi -o $@ + +# Download OVMF firmware for QEMU +$(BUILD)/OVMF_CODE.fd $(BUILD)/OVMF_VARS.fd: + mkdir -p $(BUILD) + curl -L https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF_CODE.fd -o $(BUILD)/OVMF_CODE.fd + curl -L https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF_VARS.fd -o $(BUILD)/OVMF_VARS.fd $(BUILD)/UEFI-Shell-fwk.iso: $(BUILD)/boot.efi $(BUILD)/shellx64.efi mkdir -p $(BUILD)/$@.tmp/efi/boot @@ -66,3 +83,55 @@ $(BUILD)/boot.efi: ../Cargo.lock $(SRC_DIR)/Cargo.toml $(SRC_DIR)/src/* --release \ -- \ --emit link=framework_uefi/$@ + +# Test targets +$(BUILD)/ovmf_vars.fd: $(BUILD)/OVMF_VARS.fd + cp $< $@ + +$(BUILD)/test.img: $(BUILD)/boot.efi $(BUILD)/shellx64.efi tests/test.nsh winux.bin + dd if=/dev/zero of=$@.tmp bs=512 count=131072 + mkfs.vfat $@.tmp + mmd -i $@.tmp efi + mmd -i $@.tmp efi/boot + # Copy shell as boot loader, our tool as fwk.efi + mcopy -i $@.tmp $(BUILD)/shellx64.efi ::efi/boot/bootx64.efi + mcopy -i $@.tmp $(BUILD)/boot.efi ::efi/boot/fwk.efi + # Also copy as bootx64 location for the test script + mcopy -i $@.tmp $(BUILD)/boot.efi ::bootx64.efi + # Copy test script as startup.nsh + mcopy -i $@.tmp tests/test.nsh ::startup.nsh + # Copy test files + mcopy -i $@.tmp winux.bin ::winux.bin + mv $@.tmp $@ + +$(BUILD)/test-boot.img: $(BUILD)/test.img + dd if=/dev/zero of=$@.tmp bs=512 count=133120 + parted $@.tmp -s -a minimal mklabel gpt + parted $@.tmp -s -a minimal mkpart EFI FAT16 2048s 131071s + parted $@.tmp -s -a minimal toggle 1 boot + dd if=$< of=$@.tmp bs=512 count=131072 seek=2048 conv=notrunc + mv $@.tmp $@ + +test-qemu: $(BUILD)/test-boot.img $(BUILD)/OVMF_CODE.fd $(BUILD)/ovmf_vars.fd + @echo "Running UEFI tests in QEMU..." + @rm -f $(BUILD)/serial.log + timeout 60 $(QEMU) $(QEMU_TEST_FLAGS) -drive format=raw,file=$< || true + @echo "" + @echo "=== Test Output ===" + @cat $(BUILD)/serial.log + @echo "" + @echo "=== Test Results ===" + @if grep -q "TESTS_COMPLETE" $(BUILD)/serial.log; then \ + echo "All tests completed."; \ + else \ + echo "ERROR: Tests did not complete!"; \ + exit 1; \ + fi + @if grep -q "TEST_FAILED" $(BUILD)/serial.log; then \ + echo "ERROR: Some tests failed!"; \ + grep "TEST_FAILED" $(BUILD)/serial.log; \ + exit 1; \ + fi + @echo "All tests passed!" + +test: test-qemu diff --git a/framework_uefi/tests/test.nsh b/framework_uefi/tests/test.nsh new file mode 100644 index 00000000..2795e091 --- /dev/null +++ b/framework_uefi/tests/test.nsh @@ -0,0 +1,82 @@ +@echo -off +echo "=== UEFI Test Suite Starting ===" + +# Clean up any files from previous test runs +if exist fs0:\dump.bmp then + del fs0:\dump.bmp +endif + +# Set path to our tool (fwk.efi is our framework tool) +set fwk fs0:\efi\boot\fwk.efi + +echo "" +echo "=== TEST: --version ===" +%fwk% --version +if %lasterror% == 0 then + echo "TEST_PASSED: version" +else + echo "TEST_FAILED: version (exit code %lasterror%)" +endif + +echo "" +echo "=== TEST: --help ===" +%fwk% --help +# --help returns 1 (LOAD_ERROR) which is expected behavior for this tool +if %lasterror% == 0x1 then + echo "TEST_PASSED: help" +else + echo "TEST_FAILED: help (expected 0x1, got %lasterror%)" +endif + +echo "" +echo "=== TEST: --hash on tool itself ===" +%fwk% --hash fs0:\efi\boot\fwk.efi +if %lasterror% == 0 then + echo "TEST_PASSED: hash" +else + echo "TEST_FAILED: hash (exit code %lasterror%)" +endif + +echo "" +echo "=== TEST: --hash on winux.bin ===" +%fwk% --hash fs0:\winux.bin +if %lasterror% == 0 then + echo "TEST_PASSED: hash_winux" +else + echo "TEST_FAILED: hash_winux (exit code %lasterror%)" +endif + +echo "" +echo "=== TEST: --capsule dump ===" +%fwk% --capsule fs0:\winux.bin --dump fs0:\dump.bmp +if %lasterror% == 0 then + echo "TEST_PASSED: capsule_dump" +else + echo "TEST_FAILED: capsule_dump (exit code %lasterror%)" +endif + +echo "" +echo "=== TEST: verify dump.bmp was created ===" +if exist fs0:\dump.bmp then + %fwk% --hash fs0:\dump.bmp + if %lasterror% == 0 then + echo "TEST_PASSED: dump_exists" + else + echo "TEST_FAILED: dump_exists (hash command failed)" + endif +else + echo "TEST_FAILED: dump_exists (dump.bmp was not created)" +endif + +echo "" +echo "=== TEST: introspect (may fail in QEMU without real SMBIOS) ===" +%fwk% --introspect +# Don't fail on this - QEMU doesn't have real Framework SMBIOS +echo "TEST_INFO: introspect exited with %lasterror%" + +echo "" +echo "=== UEFI Test Suite Complete ===" +echo "TESTS_COMPLETE" + +# Shutdown QEMU +reset -s diff --git a/framework_uefi/winux.bin b/framework_uefi/winux.bin new file mode 100644 index 0000000000000000000000000000000000000000..7cd1956f95ee3f48641823a7b4cf16e127c4425b GIT binary patch literal 676898 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 Date: Mon, 26 Jan 2026 14:11:00 +0800 Subject: [PATCH 9/9] cargo fmt Signed-off-by: Daniel Schaefer --- framework_lib/src/fw_uefi/fs.rs | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/framework_lib/src/fw_uefi/fs.rs b/framework_lib/src/fw_uefi/fs.rs index b4399036..a58b1df3 100644 --- a/framework_lib/src/fw_uefi/fs.rs +++ b/framework_lib/src/fw_uefi/fs.rs @@ -59,11 +59,7 @@ pub fn shell_read_file(path: &str) -> Option> { let mut buffer: Vec = vec![0; file_size as usize]; let mut read_size = file_size as usize; - let status = (shell.read_file)( - file_handle, - &mut read_size, - buffer.as_mut_ptr().cast(), - ); + let status = (shell.read_file)(file_handle, &mut read_size, buffer.as_mut_ptr().cast()); let _ = (shell.close_file)(file_handle); @@ -78,26 +74,19 @@ pub fn shell_read_file(path: &str) -> Option> { pub fn shell_write_file(path: &str, data: &[u8]) -> Result { let shell = get_shell_protocol(); - let c_path = CString16::try_from(path).map_err(|_| uefi::Error::from(Status::INVALID_PARAMETER))?; + let c_path = + CString16::try_from(path).map_err(|_| uefi::Error::from(Status::INVALID_PARAMETER))?; unsafe { let mode = FileMode::READ | FileMode::WRITE | FileMode::CREATE; let mut handle: MaybeUninit = MaybeUninit::zeroed(); - (shell.open_file_by_name)( - c_path.as_ptr().cast(), - handle.as_mut_ptr(), - mode.bits(), - ) - .to_result()?; + (shell.open_file_by_name)(c_path.as_ptr().cast(), handle.as_mut_ptr(), mode.bits()) + .to_result()?; let file_handle = handle.assume_init(); let mut write_size = data.len(); - let status = (shell.write_file)( - file_handle, - &mut write_size, - data.as_ptr() as *mut _, - ); + let status = (shell.write_file)(file_handle, &mut write_size, data.as_ptr() as *mut _); let _ = (shell.close_file)(file_handle);