lanzaboote/rust/src/main.rs

127 lines
3.1 KiB
Rust
Raw Normal View History

2022-11-21 05:44:04 -05:00
#![no_main]
#![no_std]
#![feature(abi_efiapi)]
extern crate alloc;
2022-11-21 10:22:44 -05:00
2022-11-21 19:13:41 -05:00
use alloc::vec::Vec;
use core::ops::Deref;
use log::debug;
use uefi::{
prelude::*,
proto::{
console::text::Output,
device_path::DevicePath,
loaded_image::LoadedImage,
media::{
2022-11-21 19:13:41 -05:00
file::{Directory, File, FileAttribute, FileMode, RegularFile},
fs::SimpleFileSystem,
},
},
table::boot::{OpenProtocolAttributes, OpenProtocolParams},
Result,
};
2022-11-21 10:22:44 -05:00
fn print_logo(output: &mut Output) {
output.clear().unwrap();
output
.output_string(cstr16!(
"
_ _ _ \r
| | | | | | \r
| | __ _ _ __ ______ _| |__ ___ ___ | |_ \r
| |/ _` | '_ \\|_ / _` | '_ \\ / _ \\ / _ \\| __|\r
| | (_| | | | |/ / (_| | |_) | (_) | (_) | |_ \r
|_|\\__,_|_| |_/___\\__,_|_.__/ \\___/ \\___/ \\__|\r
"
))
.unwrap();
}
2022-11-21 05:44:04 -05:00
// Find the root directory of the given image.
//
// # 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 = boot_services.open_protocol::<SimpleFileSystem>(
OpenProtocolParams {
handle: fs_handle,
agent: image,
controller: None,
},
OpenProtocolAttributes::Exclusive,
)?;
file_system.open_volume()
}
2022-11-21 19:13:41 -05:00
fn read_all(image: &mut RegularFile) -> Result<Vec<u8>> {
let mut buf = Vec::new();
// TODO Can we do this nicer?
loop {
let mut chunk = [0; 512];
let read_bytes = image.read(&mut chunk).map_err(|e| e.status())?;
if read_bytes == 0 {
break;
}
buf.extend_from_slice(&chunk[0..read_bytes]);
}
Ok(buf)
}
2022-11-21 05:44:04 -05:00
#[entry]
fn main(handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
2022-11-21 05:44:04 -05:00
uefi_services::init(&mut system_table).unwrap();
2022-11-21 10:22:44 -05:00
print_logo(system_table.stdout());
2022-11-21 09:36:39 -05:00
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");
2022-11-21 19:13:41 -05:00
debug!(
"Data: {}",
alloc::str::from_utf8(&read_all(&mut file).unwrap()).unwrap()
);
2022-11-21 05:44:04 -05:00
Status::SUCCESS
}