allocate buffer, don't actually do anything with it

This commit is contained in:
Artemis Tosini 2024-07-31 21:49:51 +00:00
parent bf71132cd0
commit 2c44538f72
Signed by: artemist
GPG key ID: EE5227935FE3FF18
4 changed files with 76 additions and 44 deletions

45
Cargo.lock generated
View file

@ -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"

View file

@ -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 }

View file

@ -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<Boot>) -> Status {
fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> 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::<NativeEndian>::minimal_parse(&staging_buf).expect("Failed to parse kernel");
info!("Kernel is {:?}", header.ehdr.class);
loop {
system_table.boot_services().stall(10_000_000);
}
}

36
src/staging.rs Normal file
View file

@ -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) }
}