From 2c44538f72b063dcfa8dc19a908c7e2fd47c7a4d Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Wed, 31 Jul 2024 21:49:51 +0000 Subject: [PATCH] allocate buffer, don't actually do anything with it --- Cargo.lock | 45 +++++++-------------------------------------- Cargo.toml | 2 +- src/main.rs | 37 ++++++++++++++++++++++++++++++++----- src/staging.rs | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 44 deletions(-) create mode 100644 src/staging.rs diff --git a/Cargo.lock b/Cargo.lock index 30a555e..7d7c7e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,38 +20,27 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + [[package]] name = "freeloader" version = "0.1.0" dependencies = [ - "goblin", + "elf", "log", "uefi", ] -[[package]] -name = "goblin" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" -dependencies = [ - "log", - "plain", - "scroll", -] - [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - [[package]] name = "proc-macro2" version = "1.0.86" @@ -90,26 +79,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "scroll" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" -dependencies = [ - "scroll_derive", -] - -[[package]] -name = "scroll_derive" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.72", -] - [[package]] name = "syn" version = "1.0.109" diff --git a/Cargo.toml b/Cargo.toml index 97badc6..e47be2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" [dependencies] uefi = { version = "0.29.0", default-features = false, features = [ "alloc", "global_allocator", "panic_handler", "logger" ] } log = { version = "0.4.22", default-features = false } -goblin = { version = "0.8.2", default_features = false, features = [ "elf32", "elf64", "alloc" ] } +elf = { version = "0.7.4", default_features = false } diff --git a/src/main.rs b/src/main.rs index 42591aa..b4dc398 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,14 +2,41 @@ #![no_std] mod abi; +mod staging; +use elf::endian::NativeEndian; use log::info; -use uefi::prelude::*; +use uefi::{fs::FileSystem, prelude::*}; #[entry] -fn main(_image_handle: Handle, mut system_table: SystemTable) -> Status { +fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { uefi::helpers::init(&mut system_table).unwrap(); - info!("Hello, world!"); - system_table.boot_services().stall(10_000_000); - Status::SUCCESS + + info!("Starting freeloader"); + + let staging_buf = staging::allocate_staging(system_table.boot_services()); + + let mut esp = FileSystem::new( + system_table + .boot_services() + .get_image_file_system(image_handle) + .expect("Failed to get ESP handle"), + ); + + let kernel = esp + .read(cstr16!("efi\\freebsd\\kernel")) + .expect("Failed to read kernel"); + + info!("Loaded kernel"); + + staging_buf[..kernel.len()].copy_from_slice(&kernel); + + let header = + elf::ElfBytes::::minimal_parse(&staging_buf).expect("Failed to parse kernel"); + + info!("Kernel is {:?}", header.ehdr.class); + + loop { + system_table.boot_services().stall(10_000_000); + } } diff --git a/src/staging.rs b/src/staging.rs new file mode 100644 index 0000000..3ff8ccc --- /dev/null +++ b/src/staging.rs @@ -0,0 +1,36 @@ +use log::info; +use uefi::table::boot::{AllocateType, BootServices, MemoryType}; + +/// Size of the staging buffer for preloaded files +const STAGING_BUF_SIZE: usize = 64 * 1024 * 1024; +const STAGING_BUF_NUM_PAGES: usize = STAGING_BUF_SIZE / uefi::table::boot::PAGE_SIZE; + +const ADDR_ROUND: u64 = 2 * 1024 * 1024; + +pub fn allocate_staging(boot_services: &BootServices) -> &'static mut [u8] { + let allocation_type = if cfg!(target_arch = "x86_64") { + // Must be under 4GiB because we need to pass a 32-bit pointer + AllocateType::MaxAddress(4 * 1024 * 1024 * 1024) + } else { + AllocateType::AnyPages + }; + + let base = boot_services + .allocate_pages( + allocation_type, + MemoryType::LOADER_CODE, + STAGING_BUF_NUM_PAGES, + ) + .expect("Unable to allocate staging area"); + + // Some architectures want a kernel on a 2MiB boundary, do it everywhere + let rounded = ((base + ADDR_ROUND - 1) / ADDR_ROUND) * ADDR_ROUND; + + let available_size = STAGING_BUF_SIZE - ((rounded - base) as usize); + info!( + "Allocated {:#018x} byte staging buffer at {:#018x}", + available_size, rounded + ); + + unsafe { core::slice::from_raw_parts_mut(rounded as *mut u8, available_size) } +}