diff --git a/rust/src/main.rs b/rust/src/main.rs index 0651e64..f2baec7 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -2,9 +2,24 @@ #![no_std] #![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) { output.clear().unwrap(); @@ -23,11 +38,73 @@ fn print_logo(output: &mut Output) { .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 { + let loaded_image = boot_services.open_protocol::( + OpenProtocolParams { + handle: image, + agent: image, + controller: None, + }, + OpenProtocolAttributes::Exclusive, + )?; + + let device_handle = loaded_image.device(); + + let device_path = boot_services.open_protocol::( + 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::(&mut device_path)?; + + let mut file_system_raw = boot_services.open_protocol::( + 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] -fn main(_handle: Handle, mut system_table: SystemTable) -> Status { +fn main(handle: Handle, mut system_table: SystemTable) -> Status { uefi_services::init(&mut system_table).unwrap(); 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 }