Question: How should I properly pass system table to the kernel to enable runtime services after v0.32?
GZTimeWalker opened this issue · 5 comments
Hi! I have a UEFI boot loader, which load kernel ELF and jump to its entry.
After upgrade to v0.32, all things about system table seems to be static variable.
I added uefi crate for my kernel, and I tried to use uefi::runtime, but I got global system table pointer is not set.
I looked up the relevant comments and it seems that the setter function should not be called manually.
And all templates / examples / docs have nothing about this upgrade, so how should I properly pass system table to the kernel to enable runtime services?
Hey! You can set it like this in your kernel:
https://github.com/rust-osdev/uefi-rs/blob/main/uefi-std-example/src/main.rs#L19
In the uefi loader, it should be set automatically when you use our entry macro for the main function.
You have to pass the value somehow to your kernel and call the function referenced above there, when you want to use it in the kernel.
The global static from the loader and from your kernel to hold the table ptr are not the same
But the SystemTable is also marked as deprecated, should I ignore the type and just pass pointer (like *const u8)?
Note: Without using uefi_raw, we cannot get a pointer of type *const uefi_raw::table::system::SystemTable.
Further, how do I get the address of this static variable for https://github.com/rust-osdev/uefi-rs/blob/main/uefi/src/table/mod.rs?
Should I just copy it entirely instead? But it looks not elegant.
There is no need for the deprecated SystemTable symbol and you can access the global static via uefi::table::system_table_raw() and uefi::table::set_system_table(). I think there is no need to import uefi_raw::table::system::SystemTable as you can simply call .cast() on the ptr.
I think something like this should work:
// in uefi loader
let ptr = uefi::table::system_table_raw().unwrap();
let ptr = ptr.cast::<core::ffi::c_void>();
boot_info.write(boot_info_offset::UEFI_ST, ptr.as_ptr() /* unwrap NonNull */);
// in kernel
let ptr = boot_info.get(boot_info_offset::UEFI_ST);
uefi::table::set_system_table(ptr.cast());There is no need for the deprecated SystemTable symbol and you can access the global static via
uefi::table::system_table_raw()anduefi::table::set_system_table(). I think there is no need to importuefi_raw::table::system::SystemTableas you can simply call.cast()on the ptr.I think something like this should work:
// in uefi loader let ptr = uefi::table::system_table_raw().unwrap(); let ptr = ptr.cast::<core::ffi::c_void>(); boot_info.write(boot_info_offset::UEFI_ST, ptr.as_ptr() /* unwrap NonNull */); // in kernel let ptr = boot_info.get(boot_info_offset::UEFI_ST); uefi::table::set_system_table(ptr.cast());
That works, thank you!
btw, it should use uefi::table::set_system_table(ptr.cast().as_ptr());