Skip to content

Commit c3b0e26

Browse files
committed
feat(uefi): allow printing after exiting boot services
Signed-off-by: Martin Kröning <martin.kroening@eonerc.rwth-aachen.de>
1 parent e546969 commit c3b0e26

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

src/arch/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cfg_if::cfg_if! {
55
} else if #[cfg(target_arch = "riscv64")] {
66
mod riscv64;
77
pub use self::riscv64::*;
8-
} else if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
8+
} else if #[cfg(all(target_arch = "x86_64"))] {
99
mod x86_64;
1010
pub use self::x86_64::*;
1111
}

src/arch/x86_64/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@ cfg_if::cfg_if! {
99
}
1010

1111
mod console;
12+
#[cfg(target_os = "none")]
1213
mod paging;
14+
#[cfg(target_os = "none")]
1315
mod physicalmem;
1416

1517
pub use console::Console;
1618

19+
#[cfg(target_os = "none")]
1720
const KERNEL_STACK_SIZE: u64 = 32_768;
21+
#[cfg(target_os = "none")]
1822
const SERIAL_IO_PORT: u16 = 0x3F8;
1923

24+
#[cfg(target_os = "none")]
2025
unsafe fn map_memory(address: usize, memory_size: usize) -> usize {
2126
use align_address::Align;
2227
use x86_64::structures::paging::{PageSize, PageTableFlags, Size2MiB};
@@ -29,6 +34,7 @@ unsafe fn map_memory(address: usize, memory_size: usize) -> usize {
2934
address
3035
}
3136

37+
#[cfg(target_os = "none")]
3238
pub unsafe fn get_memory(memory_size: u64) -> u64 {
3339
use align_address::Align;
3440
use x86_64::structures::paging::{PageSize, Size2MiB};

src/os/uefi/console.rs

+55-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,66 @@
1+
use core::ffi::c_void;
12
use core::fmt;
3+
use core::ptr::NonNull;
4+
use core::sync::atomic::{AtomicBool, Ordering};
25

36
use one_shot_mutex::OneShotMutex;
7+
use uefi::table::boot::{EventType, Tpl};
8+
use uefi::table::{Boot, SystemTable};
9+
use uefi::Event;
410

5-
pub struct Console(());
11+
use crate::arch;
12+
13+
pub enum Console {
14+
None,
15+
BootServices,
16+
Native { console: arch::Console },
17+
}
18+
19+
impl Console {
20+
const fn new() -> Self {
21+
Self::None
22+
}
23+
24+
fn exit_boot_services(&mut self) {
25+
assert!(matches!(self, Self::BootServices { .. }));
26+
*self = Self::Native {
27+
console: arch::Console::default(),
28+
};
29+
}
30+
31+
fn init(&mut self) {
32+
assert!(matches!(self, Console::None));
33+
unsafe {
34+
uefi_services::system_table()
35+
.boot_services()
36+
.create_event(
37+
EventType::SIGNAL_EXIT_BOOT_SERVICES,
38+
Tpl::NOTIFY,
39+
Some(exit_boot_services),
40+
None,
41+
)
42+
.unwrap();
43+
}
44+
*self = Console::BootServices;
45+
}
46+
}
647

748
impl fmt::Write for Console {
849
fn write_str(&mut self, s: &str) -> fmt::Result {
9-
uefi_services::system_table().stdout().write_str(s)?;
50+
match self {
51+
Console::None => {
52+
self.init();
53+
self.write_str(s)?;
54+
}
55+
Console::BootServices => uefi_services::system_table().stdout().write_str(s)?,
56+
Console::Native { console } => console.write_bytes(s.as_bytes()),
57+
}
1058
Ok(())
1159
}
1260
}
1361

14-
pub static CONSOLE: OneShotMutex<Console> = OneShotMutex::new(Console(()));
62+
unsafe extern "efiapi" fn exit_boot_services(_e: Event, _ctx: Option<NonNull<c_void>>) {
63+
CONSOLE.lock().exit_boot_services();
64+
}
65+
66+
pub static CONSOLE: OneShotMutex<Console> = OneShotMutex::new(Console::new());

0 commit comments

Comments
 (0)