Add code that reads a file from the ESP

This commit is contained in:
Julian Stecklina 2022-11-21 17:52:06 +01:00
parent 4970dafdbf
commit 6e13511b4d
1 changed files with 80 additions and 3 deletions

View File

@ -2,9 +2,24 @@
#![no_std] #![no_std]
#![feature(abi_efiapi)] #![feature(abi_efiapi)]
use uefi::{prelude::*, proto::console::text::Output}; extern crate alloc;
mod boot_image; use core::ops::Deref;
use log::debug;
use uefi::{
prelude::*,
proto::{
console::text::Output,
device_path::DevicePath,
loaded_image::LoadedImage,
media::{
file::{Directory, File, FileAttribute, FileMode},
fs::SimpleFileSystem,
},
},
table::boot::{OpenProtocolAttributes, OpenProtocolParams},
Result,
};
fn print_logo(output: &mut Output) { fn print_logo(output: &mut Output) {
output.clear().unwrap(); output.clear().unwrap();
@ -23,11 +38,73 @@ fn print_logo(output: &mut Output) {
.unwrap(); .unwrap();
} }
// # Safety
//
// TODO Need to find out whether we can open the protocols in safe code.
unsafe fn root_directory(image: Handle, boot_services: &BootServices) -> Result<Directory> {
let loaded_image = boot_services.open_protocol::<LoadedImage>(
OpenProtocolParams {
handle: image,
agent: image,
controller: None,
},
OpenProtocolAttributes::Exclusive,
)?;
let device_handle = loaded_image.device();
let device_path = boot_services.open_protocol::<DevicePath>(
OpenProtocolParams {
handle: device_handle,
agent: image,
controller: None,
},
OpenProtocolAttributes::Exclusive,
)?;
let mut device_path: &DevicePath = device_path.deref();
let fs_handle = boot_services.locate_device_path::<SimpleFileSystem>(&mut device_path)?;
let mut file_system_raw = boot_services.open_protocol::<SimpleFileSystem>(
OpenProtocolParams {
handle: fs_handle,
agent: image,
controller: None,
},
OpenProtocolAttributes::Exclusive,
)?;
let file_system: &mut SimpleFileSystem = &mut file_system_raw;
let root = file_system.open_volume()?;
Ok(root)
}
#[entry] #[entry]
fn main(_handle: Handle, mut system_table: SystemTable<Boot>) -> Status { fn main(handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
uefi_services::init(&mut system_table).unwrap(); uefi_services::init(&mut system_table).unwrap();
print_logo(system_table.stdout()); print_logo(system_table.stdout());
let boot_services = system_table.boot_services();
let mut root = unsafe { root_directory(handle, boot_services).unwrap() };
debug!("Found root");
let mut file = root
.open(cstr16!("foo.txt"), FileMode::Read, FileAttribute::empty())
.unwrap()
.into_regular_file()
.unwrap();
debug!("Opened file");
let mut buf = [0; 512];
let bytes_read = file.read(&mut buf).unwrap();
let data = &buf[0..bytes_read];
debug!("Data: {}", alloc::str::from_utf8(&data).unwrap());
Status::SUCCESS Status::SUCCESS
} }