I am making a basic uefi application that is supposed to load an elf kernel. I have gotten to the point that I have the fille loaded, and a buffer with the file info. But to actually read the file and do anything with it, I need to know the file size so I can make the buffer for it. I know uefi-rs has a FileInfo
struct, but I do not know how to cast the buffer I have to this struct.
I have tried looking for solutions to similar problems, came across this Transmuting u8 buffer to struct in Rust. None of these solutions worked, I kept getting an error with the answers on that page because I cannot cast the thin u8 pointer to the fat FileInfo
pointer.
This is my source code so far:
#![no_main]
#![no_std]
#![feature(abi_efiapi)]
#![allow(stable_features)]
#[macro_use]
extern crate alloc;
use elf_rs::{Elf, ElfFile};
use log::info;
use uefi::{prelude::{entry, BootServices, cstr16}, Handle, table::{SystemTable, Boot}, Status, Char16, proto::{loaded_image::LoadedImage, media::{file::{File, FileHandle, FileMode, FileAttribute, FileInfo}, fs::SimpleFileSystem}}, CStr16, data_types::Align};
fn load_file(path: &CStr16, boot_services: &BootServices) -> FileHandle {
let loaded_image = boot_services.open_protocol_exclusive::<LoadedImage>(boot_services.image_handle()).unwrap();
let mut file_system = boot_services.open_protocol_exclusive::<SimpleFileSystem>(loaded_image.device()).unwrap();
let mut directory = file_system.open_volume().unwrap();
directory.open(path, FileMode::Read, FileAttribute::READ_ONLY).unwrap()
}
#[entry]
fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
uefi_services::init(&mut system_table).unwrap();
info!("Loading kernel...");
let mut kernel = load_file(cstr16!("kernel.elf"), system_table.boot_services()).into_regular_file().unwrap();
let mut small_buffer = vec![0u8; 0];
let size = kernel.get_info::<FileInfo>(&mut small_buffer).err().unwrap().data().unwrap();
let mut file_info = vec![0u8; size];
kernel.get_info::<FileInfo>(&mut file_info);
let info: FileInfo; //this is what I need
let elf_buffer = vec![0u8; info.file_size().try_into().unwrap()];
let elf = Elf::from_bytes(&mut elf_buffer).expect("Kernel loading failed!");
info!("{:?} header: {:?}", elf, elf.elf_header());
for p in elf.program_header_iter() {
info!("{:x?}", p);
}
for s in elf.section_header_iter() {
info!("{:x?}", s);
}
let s = elf.lookup_section(b".text");
info!("s {:?}", s);
system_table.boot_services().stall(100_000_000);
Status::SUCCESS
}