Skip to content

Commit 2b8e5e2

Browse files
committed
uefi-fs: initial commit
1 parent 22f6869 commit 2b8e5e2

12 files changed

+1214
-1
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
resolver = "2"
33
members = [
44
"template",
5+
"uefi-fs",
56
"uefi-macros",
67
"uefi-services",
78
"uefi-test-runner",
@@ -10,5 +11,6 @@ members = [
1011

1112
[patch.crates-io]
1213
uefi = { path = "uefi" }
14+
uefi-fs = { path = "uefi-fs" }
1315
uefi-macros = { path = "uefi-macros" }
1416
uefi-services = { path = "uefi-services" }

uefi-fs/Cargo.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[package]
2+
name = "uefi-fs"
3+
version = "1.0.0"
4+
authors = ["The Rust OSDev team"]
5+
readme = "README.md"
6+
edition = "2021"
7+
description = """
8+
File-system abstraction for the uefi-crate that is close to Rust's standard
9+
libraries `fs` module.
10+
"""
11+
repository = "https://github.com/rust-osdev/uefi-rs"
12+
keywords = ["uefi", "fs", "file-system"]
13+
categories = ["embedded", "no-std"]
14+
license = "MPL-2.0"
15+
16+
[dependencies]
17+
# uefi = { version = "0.18.0", features = ["alloc", "logger"] }
18+
uefi = { path = "../uefi" , features = ["alloc", "logger"] }
19+
log = { version = "0.4.5", default-features = false }
20+
derive_more = { version = "0.99", default-features = false, features = ["display"]}

uefi-fs/LICENSE

Lines changed: 373 additions & 0 deletions
Large diffs are not rendered by default.

uefi-fs/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# uefi-services
2+
3+
[![Crates.io](https://img.shields.io/crates/v/uefi-services)](https://crates.io/crates/uefi-services)
4+
[![Docs.rs](https://docs.rs/uefi-macros/badge.svg)](https://docs.rs/uefi-services)
5+
6+
This crate enables you some convenience features on top of the
7+
[`uefi`](https://crates.io/crates/uefi) crate. It includes a panic handler, a logger, and
8+
a global allocator.
9+
10+
`uefi-services` is part of the `uefi-rs` project. Please refer to
11+
<https://github.com/rust-osdev/uefi-rs/> for comprehensive documentation.
12+
13+
## Optional features
14+
15+
This crate's features are described in [`src/lib.rs`].
16+
17+
[`src/lib.rs`]: src/lib.rs

uefi-fs/src/dir_entry_iter.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use super::*;
2+
use alloc::boxed::Box;
3+
use alloc::vec::Vec;
4+
use uefi::Result;
5+
6+
pub struct UefiError;
7+
8+
/// Iterates over the entries of an UEFI directory. It returns boxed values of
9+
/// type [`UefiFileInfo`].
10+
pub struct UefiDirectoryIter(UefiDirectoryHandle);
11+
12+
impl UefiDirectoryIter {
13+
/// Constructor.
14+
pub(crate) fn new(handle: UefiDirectoryHandle) -> Self {
15+
Self(handle)
16+
}
17+
}
18+
19+
impl Iterator for UefiDirectoryIter {
20+
type Item = Result<Box<UefiFileInfo>, ()>;
21+
22+
fn next(&mut self) -> Option<Self::Item> {
23+
let e = self.0.read_entry_boxed();
24+
match e {
25+
// no more entries
26+
Ok(None) => None,
27+
Ok(Some(e)) => Some(Ok(e)),
28+
Err(e) => Some(Err(e)),
29+
}
30+
}
31+
}

uefi-fs/src/file_info.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::path::MAX_COMPONENT_LENGTH;
2+
use alloc::vec::Vec;
3+
use core::ops::Deref;
4+
use uefi::proto::media::file::FileInfo as UefiFileInfo;
5+
6+
// Ugly but we can't use size_of() as the type isn't sized.
7+
// This is constant, as it is specified.
8+
/// Size of a [UefiFileInfo] without the filename and without a NULL byte.
9+
pub const UEFI_FILE_INFO_MAX_SIZE: usize = 80 + 2 * (1 + MAX_COMPONENT_LENGTH);
10+
11+
/// A UEFI file info that lives on the heap. Owns the data.
12+
#[derive(Debug)]
13+
pub struct BoxedUefiFileInfo {
14+
// owning buffer
15+
buffer: Vec<u8>,
16+
}
17+
18+
impl BoxedUefiFileInfo {
19+
pub fn new(info: &UefiFileInfo) -> Self {
20+
let mut buffer = Vec::<u8>::with_capacity(UEFI_FILE_INFO_MAX_SIZE);
21+
(0..buffer.capacity()).for_each(|_| buffer.push(0));
22+
23+
unsafe {
24+
let src_ptr = core::ptr::addr_of!(*info).cast::<u8>();
25+
let dest_ptr = buffer.as_mut_ptr().cast::<u8>();
26+
core::ptr::copy_nonoverlapping(src_ptr, dest_ptr, UEFI_FILE_INFO_MAX_SIZE);
27+
}
28+
Self { buffer }
29+
}
30+
}
31+
32+
impl Deref for BoxedUefiFileInfo {
33+
type Target = UefiFileInfo;
34+
fn deref(&self) -> &Self::Target {
35+
unsafe {
36+
let addr = self.buffer.as_ptr().cast::<()>();
37+
let ptr: *const UefiFileInfo =
38+
// todo metadata is here probably unused?!
39+
core::ptr::from_raw_parts(addr, self.buffer.capacity());
40+
ptr.as_ref().unwrap()
41+
}
42+
}
43+
}
44+
45+
#[cfg(test)]
46+
mod tests {
47+
use super::*;
48+
use uefi::proto::media::file::FromUefi;
49+
50+
#[test]
51+
fn test_put_into_box() {
52+
let mut buffer = [0_u8; UEFI_FILE_INFO_MAX_SIZE];
53+
54+
let boxed_fileinfo = unsafe {
55+
let ptr = buffer.as_mut_ptr();
56+
57+
// set some values to the "file_size" property
58+
*ptr.cast::<u64>().add(1) = 0x7733_0909_2345_1337;
59+
60+
let uefi_fileinfo = UefiFileInfo::from_uefi(ptr.cast());
61+
assert_eq!(uefi_fileinfo.file_size(), 0x7733_0909_2345_1337);
62+
BoxedUefiFileInfo::new(uefi_fileinfo)
63+
};
64+
65+
assert_eq!(boxed_fileinfo.file_size(), 0x7733_0909_2345_1337);
66+
}
67+
}

0 commit comments

Comments
 (0)