1

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
}
Olle
  • 81
  • 5
  • Skimming the docs, it looks like `kernel.get_info()` returns the passed reference already cast to the proper value. So I guess `let info = kernel.get_info::(&mut file_info).unwrap();` should do the trick. – rodrigo Jan 18 '23 at 14:58

0 Answers0