Closed OrdChaos closed 3 months ago
Hey there!
First, I'd like to ask you to provide an example that compiles and runs the next time you are asking for help. This makes it much easier to reproduce.
I stripped down your example to a version that compiles:
#![no_main]
#![no_std]
use log::info;
use uefi::prelude::*;
use uefi::println;
use uefi::table::boot::MemoryType;
#[entry]
fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
uefi::helpers::init(&mut system_table).unwrap()
//Exit Boot Services
log::info!("Now Exit the Boot Services");
let _ = unsafe {
let _x = system_table.exit_boot_services(MemoryType::BOOT_SERVICES_DATA);
};
log::info!("Exited boot services");
loop {}
}
Here, I can't reproduce anything.
Tip: For debugging, you locally can put your minimal reproducer into <uefi-repo>/uefi-test-runner/examples/your_example.rs
and run it using cargo xtask run --example your-example
. The <uefi-repo>/integration-test-debugcon.log
file will contain log messages even after boot services have been exited.
Perhaps you can debug further with that.
OK
For now, I've found that the problem I met isn't how I can exit(Maybe I don't understand the docs correctly) It is just I can't get the correct entry_size and map_size for me, map_size / entry_size == 111
however, when i try to check every desc, the last few is like this: type = EfiReservedMemoryType size = (a big number)
type = EfiReservedMemoryType size = 0
type = EfiReservedMemoryType size = 0
...... (Size is in pagination units)
We all know that the type EfiReservedMemoryType
means 0
so maybe i've tried to read some wrong data.(because size won't be 0)
How i can do to get correct data?
let memory_map_size = boot_services.memory_map_size();
let entry_size = memory_map_size.entry_size;
let map_size = memory_map_size.map_size;
Cannot I just use this? (Then I'll exit the boot services)
let (_system_table_runtime , _iter) = system_table.exit_boot_services(MemoryType::LOADER_DATA);
let memory_map_descriptors = _iter.get(0).map_or(ptr::null_mut(), |desc| desc as *const _ as *mut MemoryDescriptor);
let memory_map = MemoryMapInfo {
memory_map: memory_map_descriptors,
map_size: map_size as u64,
map_desc_size: entry_size as u64
};
I'm not sure what you are doing there. Why are you creating your own MemoryMapInfo type? The MemoryMap (see docs.rs) that is returned by uefi already combines the meta data and the memory map itself?
_iter.get(0).map_or(ptr::null_mut(), |desc| desc as *const _ as *mut MemoryDescriptor);
Here are two wrong things. First, you are possibly having a null pointer here. Why not working with Option
? Second, typing thw raw memory map as desc as *const _ as *mut MemoryDescriptor);
is illegal. It must be *const u8
and each descriptor can be found via (*const u8).add(desz_size * n).cast::<MemoryDescriptor>()
. This is unintuitive, but written in the documentation of the uefi crate and also in the UEFI spec.
I'd really want to know what you are doing there. Is something in our documentation missing that made you believe you can't use MemoryMap
from our crate?
PS: In case you really want to get the pointer to the raw memory map, use MemoryMap::as_raw
.
Any update, @OrdChaos ? Will re-open if you reply and there are things to do on our side
I've tried my best to look for the docs about how I can exit boot services in last few days. However, I don't found anything about it. I'm a green hand on this, sorry. QAQ
I know that on EDKII, I can just use BootServices->ExitBootServices(ImageHandle, Mapkey), but what should I do when I'm using this crate? I tried this:
let _ = system_table.exit_boot_services(MemoryType::BOOT_SERVICES_DATA);
But whether the memory structure changes has nothing to do with whether I execute thisAnd this:
let _ = system_table.exit_boot_services(MemoryType::CONVENTIONAL);
qemu just reboot.I have seen a signature similar to that implemented in EDKII in &BootServices, but it cannot be used for security reasons. So, ... What should I do?
Best wishes for everyone can help me (and cannot help me). QAQ
My code:
The rest parts are ok.