Skip to content

Commit 362e352

Browse files
authored
Merge pull request #571 from hermit-os/uefi-refactor
refactor(uefi): reuse ESP handle and display error chains
2 parents 8346993 + 65802cd commit 362e352

File tree

4 files changed

+72
-38
lines changed

4 files changed

+72
-38
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ uart_16550 = "0.4"
3737
x86_64 = { version = "0.15", default-features = false, features = ["instructions"] }
3838

3939
[target.'cfg(target_os = "uefi")'.dependencies]
40+
anyhow = { version = "1", default-features = false }
4041
uefi = { version = "0.36", features = ["alloc", "panic_handler", "qemu"] }
4142

4243
[build-dependencies]

src/os/uefi/mod.rs

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ use core::mem::MaybeUninit;
88
use core::{ptr, slice};
99

1010
use align_address::Align;
11+
use anyhow::anyhow;
1112
use hermit_entry::boot_info::{
1213
BootInfo, DeviceTreeAddress, HardwareInfo, PlatformInfo, SerialPortBase,
1314
};
1415
use hermit_entry::elf::{KernelObject, LoadedKernel};
15-
use log::info;
16+
use log::{error, info};
1617
use uefi::boot::{AllocateType, MemoryType, PAGE_SIZE};
1718
use uefi::fs::{self, FileSystem, Path};
1819
use uefi::prelude::*;
@@ -28,7 +29,9 @@ fn main() -> Status {
2829
uefi::helpers::init().unwrap();
2930
crate::log::init();
3031

31-
let kernel_image = read_app();
32+
let mut esp = Esp::new().unwrap();
33+
34+
let kernel_image = esp.read_app();
3235
let kernel = KernelObject::parse(&kernel_image).unwrap();
3336

3437
let kernel_memory = alloc_page_slice(kernel.mem_size()).unwrap();
@@ -45,7 +48,7 @@ fn main() -> Status {
4548
.rsdp(u64::try_from(rsdp.expose_provenance()).unwrap())
4649
.unwrap();
4750

48-
if let Some(bootargs) = read_bootargs() {
51+
if let Some(bootargs) = esp.read_bootargs() {
4952
fdt = fdt.bootargs(bootargs).unwrap();
5053
}
5154

@@ -57,41 +60,6 @@ fn main() -> Status {
5760
unsafe { boot_kernel(kernel_info, fdt) }
5861
}
5962

60-
fn read_app() -> Vec<u8> {
61-
let image_handle = boot::image_handle();
62-
let fs = boot::get_image_file_system(image_handle).expect("should open file system");
63-
64-
let path = Path::new(cstr16!(r"\EFI\BOOT\hermit-app"));
65-
66-
let data = FileSystem::new(fs)
67-
.read(path)
68-
.expect("should read file content");
69-
70-
let len = data.len();
71-
info!("Read Hermit application from \"{path}\" (size = {len} B)");
72-
73-
data
74-
}
75-
76-
fn read_bootargs() -> Option<String> {
77-
let image_handle = boot::image_handle();
78-
let fs = boot::get_image_file_system(image_handle).expect("should open file system");
79-
80-
let path = Path::new(cstr16!(r"\EFI\BOOT\hermit-bootargs"));
81-
82-
match FileSystem::new(fs).read_to_string(path) {
83-
Ok(bootargs) => {
84-
info!("Read Hermit bootargs from from \"{path}\": {bootargs}");
85-
Some(bootargs)
86-
}
87-
Err(fs::Error::Io(err)) if err.uefi_error.status() == Status::NOT_FOUND => {
88-
info!("Hermit bootargs file does not exist: \"{path}\"");
89-
None
90-
}
91-
Err(err) => panic!("{err:?}"),
92-
}
93-
}
94-
9563
pub unsafe fn boot_kernel(kernel_info: LoadedKernel, fdt: Vec<u8>) -> ! {
9664
let LoadedKernel {
9765
load_info,
@@ -153,3 +121,65 @@ fn rsdp() -> *const c_void {
153121
rsdp
154122
})
155123
}
124+
125+
pub struct Esp {
126+
fs: FileSystem,
127+
}
128+
129+
impl Esp {
130+
pub fn new() -> uefi::Result<Self> {
131+
let image_handle = boot::image_handle();
132+
let fs = boot::get_image_file_system(image_handle)?;
133+
let fs = FileSystem::new(fs);
134+
Ok(Self { fs })
135+
}
136+
137+
pub fn read_app(&mut self) -> Vec<u8> {
138+
self.read_app_at(cstr16!(r"\EFI\BOOT\hermit-app")).unwrap()
139+
}
140+
141+
pub fn read_bootargs(&mut self) -> Option<String> {
142+
self.read_bootargs_at(cstr16!(r"\EFI\BOOT\hermit-bootargs"))
143+
}
144+
145+
fn read_app_at<P: AsRef<Path>>(&mut self, path: P) -> Option<Vec<u8>> {
146+
fn inner(fs: &mut FileSystem, path: &Path) -> Option<Vec<u8>> {
147+
match fs.read(path) {
148+
Ok(data) => {
149+
let len = data.len();
150+
info!("Read Hermit application from {path} (size = {len} B)");
151+
Some(data)
152+
}
153+
Err(err) => {
154+
let err = anyhow!(err);
155+
error!("Could not read Hermit application: {err:?}");
156+
None
157+
}
158+
}
159+
}
160+
161+
inner(&mut self.fs, path.as_ref())
162+
}
163+
164+
fn read_bootargs_at<P: AsRef<Path>>(&mut self, path: P) -> Option<String> {
165+
fn inner(fs: &mut FileSystem, path: &Path) -> Option<String> {
166+
match fs.read_to_string(path) {
167+
Ok(bootargs) => {
168+
info!("Read Hermit bootargs from from {path}: {bootargs}");
169+
Some(bootargs)
170+
}
171+
Err(fs::Error::Io(err)) if err.uefi_error.status() == Status::NOT_FOUND => {
172+
info!("Hermit bootargs not found at {path}");
173+
None
174+
}
175+
Err(err) => {
176+
let err = anyhow!(err);
177+
error!("Could not read Hermit bootargs: {err:#}");
178+
None
179+
}
180+
}
181+
}
182+
183+
inner(&mut self.fs, path.as_ref())
184+
}
185+
}

xtask/src/ci/qemu.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ impl Qemu {
8383

8484
match self.build.target() {
8585
Target::X86_64Uefi => {
86+
sh.remove_path("target/esp")?;
87+
8688
// Spec: https://uefi.org/specs/UEFI/2.11/03_Boot_Manager.html#removable-media-boot-behavior
8789
// EDK II: https://github.com/tianocore/edk2/blob/edk2-stable202511/MdePkg/Include/Uefi/UefiSpec.h#L2264-L2273
8890
sh.create_dir("target/esp/EFI/BOOT")?;

0 commit comments

Comments
 (0)