Skip to content

Commit

Permalink
Update uefi-rs to 0.29
Browse files Browse the repository at this point in the history
  • Loading branch information
YtvwlD committed Sep 12, 2024
1 parent b4d2f7a commit c86e638
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 47 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion towboot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ default-target = "i686-unknown-uefi"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
uefi = { version = "0.28", features = ["alloc", "global_allocator", "logger", "panic_handler"] }
uefi = { version = "0.29", features = ["alloc", "global_allocator", "logger", "panic_handler"] }
acpi = "5.0"
smbios-lib = { git = "https://github.com/hhuOS/smbios-lib.git", branch = "main", default-features = false, features = ["no_std"] }
x86 = "0.52"
Expand Down
28 changes: 16 additions & 12 deletions towboot/src/boot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use core::ffi::c_void;
use core::ptr::NonNull;
use uefi::prelude::*;
use uefi::proto::console::gop::GraphicsOutput;
use uefi::table::system_table_boot;
use uefi::table::boot::{ScopedProtocol, MemoryType};
use uefi::table::cfg::ConfigTableEntry;

Expand All @@ -33,7 +34,6 @@ use multiboot12::information::{
};

use goblin::elf::Elf;
use uefi::helpers::system_table;

use towboot_config::{Entry, Quirk};
use super::file::File;
Expand Down Expand Up @@ -248,7 +248,9 @@ fn prepare_multiboot_information(

// This only has an effect on Multiboot2.
// TODO: Does this stay valid when we exit Boot Services?
let systab_ptr = system_table().as_ptr();
let systab_ptr = system_table_boot()
.expect("failed to get System Table")
.as_ptr();
let image_handle_ptr = (unsafe {
core::mem::transmute::<_, NonNull<c_void>>(image)
}).as_ptr();
Expand Down Expand Up @@ -356,13 +358,15 @@ impl<'a> PreparedEntry<'a> {
///
/// This function won't return.
pub(crate) fn boot(mut self, systab: SystemTable<Boot>) -> ! {
// Estimate the number of memory sections.
let map_size = systab.boot_services().memory_map_size();
let estimated_size = map_size.map_size + 500;
let estimated_count = estimated_size / map_size.entry_size;
// Get a memory map.
// This won't be completely accurate as we're still going to allocate
// and deallocate a bit, but it gives us a rough estimate.
let map = systab.boot_services().memory_map(MemoryType::LOADER_DATA)
.expect("failed to get memory map");
// Estimate how many entries there will be and add some.
let estimated_count = map.entries().len() + 5;
debug!("expecting {estimated_count} memory areas");
// You may ask yourself why we're not passing map_size.entry_size here.
// That's because we're passing a slice of uefi.rs' MemoryDescriptors
// Note that we're passing a slice of uefi.rs' MemoryDescriptors
// (which hopefully are the same as multiboot2's EFIMemoryDescs),
// and not the ones the firmware provides us with.
// (That's also why we can't set the version.)
Expand All @@ -378,16 +382,16 @@ impl<'a> PreparedEntry<'a> {
mut info, signature, update_memory_info,
) = self.multiboot_information.build();
debug!("passing signature {signature:x} to kernel...");
let mut mmap_vec = Vec::<u8>::new();
let memory_map = if self.loaded_kernel.should_exit_boot_services {
info!("exiting boot services...");
let (_systab, mut memory_map) = systab.exit_boot_services(MemoryType::LOADER_DATA);
let (_systab, mut memory_map) = unsafe {
systab.exit_boot_services(MemoryType::LOADER_DATA)
};
memory_map.sort();
// now, write! won't work anymore. Also, we can't allocate any memory.
memory_map
} else {
mmap_vec.resize(estimated_size, 0);
let memory_map = systab.boot_services().memory_map(mmap_vec.as_mut_slice()).unwrap();
let memory_map = systab.boot_services().memory_map(MemoryType::LOADER_DATA).unwrap();
debug!("got {} memory areas", memory_map.entries().len());
memory_map
};
Expand Down
65 changes: 38 additions & 27 deletions towboot/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ use core::mem::size_of;

use alloc::boxed::Box;
use alloc::collections::btree_set::BTreeSet;
use alloc::{vec::Vec, vec};
use alloc::vec::Vec;

use uefi::prelude::*;
use uefi::table::system_table_boot;
use uefi::table::boot::{AllocateType, MemoryDescriptor, MemoryType};
use uefi::helpers::system_table;

use log::{debug, warn, error};

Expand All @@ -41,7 +41,12 @@ impl Drop for Allocation {
fn drop(&mut self) {
// We can't free memory after we've exited boot services.
// But this only happens in `PreparedEntry::boot` and this function doesn't return.
unsafe { system_table().boot_services().free_pages(self.ptr, self.pages) }
unsafe {
system_table_boot()
.expect("failed to get System Table")
.boot_services()
.free_pages(self.ptr, self.pages)
}
// let's just panic if we can't free
.expect("failed to free the allocated memory");
}
Expand All @@ -60,11 +65,15 @@ impl Allocation {
/// [`move_to_where_it_should_be`]: struct.Allocation.html#method.move_to_where_it_should_be
pub(crate) fn new_at(address: usize, size: usize) -> Result<Self, Status>{
let count_pages = Self::calculate_page_count(size);
match system_table().boot_services().allocate_pages(
AllocateType::Address(address.try_into().unwrap()),
MemoryType::LOADER_DATA,
count_pages
) {
match system_table_boot()
.expect("failed to get System Table")
.boot_services()
.allocate_pages(
AllocateType::Address(address.try_into().unwrap()),
MemoryType::LOADER_DATA,
count_pages
)
{
Ok(ptr) => Ok(Allocation { ptr, len: size, pages: count_pages, should_be_at: None }),
Err(e) => {
warn!("failed to allocate {size} bytes of memory at {address:x}: {e:?}");
Expand All @@ -84,19 +93,23 @@ impl Allocation {
/// Note: This will round up to whole pages.
pub(crate) fn new_under_4gb(size: usize, quirks: &BTreeSet<Quirk>) -> Result<Self, Status> {
let count_pages = Self::calculate_page_count(size);
let ptr = system_table().boot_services().allocate_pages(
AllocateType::MaxAddress(if quirks.contains(&Quirk::ModulesBelow200Mb) {
200 * 1024 * 1024
} else {
u32::MAX.into()
}),
MemoryType::LOADER_DATA,
count_pages
).map_err(|e| {
error!("failed to allocate {size} bytes of memory: {e:?}");
dump_memory_map();
Status::LOAD_ERROR
})?;
let ptr = system_table_boot()
.expect("failed to get System Table")
.boot_services()
.allocate_pages(
AllocateType::MaxAddress(if quirks.contains(&Quirk::ModulesBelow200Mb) {
200 * 1024 * 1024
} else {
u32::MAX.into()
}),
MemoryType::LOADER_DATA,
count_pages
)
.map_err(|e| {
error!("failed to allocate {size} bytes of memory: {e:?}");
dump_memory_map();
Status::LOAD_ERROR
})?;
Ok(Allocation { ptr, len:size, pages: count_pages, should_be_at: None })
}

Expand Down Expand Up @@ -149,12 +162,10 @@ impl Allocation {
/// Show the current memory map.
fn dump_memory_map() {
debug!("memory map:");
// The docs say that we should allocate a little bit more memory than needed.
let mut buf = vec![0; system_table().boot_services()
.memory_map_size().map_size + 100
];
let mut memory_map = system_table().boot_services()
.memory_map(buf.as_mut_slice()).expect("failed to get memory map");
let mut memory_map = system_table_boot()
.expect("failed to get System Table")
.boot_services()
.memory_map(MemoryType::LOADER_DATA).expect("failed to get memory map");
memory_map.sort();
for descriptor in memory_map.entries() {
debug!("{descriptor:?}");
Expand Down

0 comments on commit c86e638

Please sign in to comment.