Skip to content

Commit 34e50ca

Browse files
Add configuration options
1 parent ab93f1b commit 34e50ca

File tree

6 files changed

+129
-17
lines changed

6 files changed

+129
-17
lines changed

api/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ fn main() {
2323
(97, 9),
2424
(106, 9),
2525
(115, 1),
26+
(116, 1),
27+
(117, 1),
2628
];
2729

2830
let mut code = String::new();

api/src/config.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ pub struct BootloaderConfig {
3131
/// Configuration for changing the level of the filter of the messages that are shown in the
3232
/// screen when booting. The default is 'Trace'.
3333
pub log_level: LevelFilter,
34+
35+
/// Configuration for enable or disable the framebuffer logger.
36+
pub frame_buffer_logger_status: LoggerStatus,
37+
38+
/// Configuration for enable or disable the serial being logger.
39+
pub serial_logger_status: LoggerStatus,
3440
}
3541

3642
impl BootloaderConfig {
@@ -39,7 +45,7 @@ impl BootloaderConfig {
3945
0x3D,
4046
];
4147
#[doc(hidden)]
42-
pub const SERIALIZED_LEN: usize = 116;
48+
pub const SERIALIZED_LEN: usize = 118;
4349

4450
/// Creates a new default configuration with the following values:
4551
///
@@ -53,6 +59,8 @@ impl BootloaderConfig {
5359
mappings: Mappings::new_default(),
5460
frame_buffer: FrameBuffer::new_default(),
5561
log_level: LevelFilter::Trace,
62+
frame_buffer_logger_status: LoggerStatus::Enable,
63+
serial_logger_status: LoggerStatus::Enable,
5664
}
5765
}
5866

@@ -67,6 +75,8 @@ impl BootloaderConfig {
6775
kernel_stack_size,
6876
frame_buffer,
6977
log_level,
78+
frame_buffer_logger_status,
79+
serial_logger_status,
7080
} = self;
7181
let ApiVersion {
7282
version_major,
@@ -147,7 +157,15 @@ impl BootloaderConfig {
147157
},
148158
);
149159

150-
concat_115_1(buf, (*log_level as u8).to_le_bytes())
160+
let log_level = concat_115_1(buf, (*log_level as u8).to_le_bytes());
161+
162+
let frame_buffer_logger_status =
163+
concat_116_1(log_level, (*frame_buffer_logger_status as u8).to_le_bytes());
164+
165+
concat_117_1(
166+
frame_buffer_logger_status,
167+
(*serial_logger_status as u8).to_le_bytes(),
168+
)
151169
}
152170

153171
/// Tries to deserialize a config byte array that was created using [`Self::serialize`].
@@ -267,6 +285,21 @@ impl BootloaderConfig {
267285
Option::None => return Err("log_level invalid"),
268286
};
269287

288+
let (&frame_buffer_logger_status, s) = split_array_ref(s);
289+
let frame_buffer_logger_status =
290+
LoggerStatus::from_u8(u8::from_le_bytes(frame_buffer_logger_status));
291+
let frame_buffer_logger_status = match frame_buffer_logger_status {
292+
Option::Some(status) => status,
293+
Option::None => return Err("frame_buffer_logger_status invalid"),
294+
};
295+
296+
let (&serial_logger_status, s) = split_array_ref(s);
297+
let serial_logger_status = LoggerStatus::from_u8(u8::from_le_bytes(serial_logger_status));
298+
let serial_logger_status = match serial_logger_status {
299+
Option::Some(status) => status,
300+
Option::None => return Err("serial_logger_status invalid"),
301+
};
302+
270303
if !s.is_empty() {
271304
return Err("unexpected rest");
272305
}
@@ -277,6 +310,8 @@ impl BootloaderConfig {
277310
mappings,
278311
frame_buffer,
279312
log_level,
313+
frame_buffer_logger_status,
314+
serial_logger_status,
280315
})
281316
}
282317

@@ -288,6 +323,8 @@ impl BootloaderConfig {
288323
kernel_stack_size: rand::random(),
289324
frame_buffer: FrameBuffer::random(),
290325
log_level: LevelFilter::Trace,
326+
frame_buffer_logger_status: LoggerStatus::Enable,
327+
serial_logger_status: LoggerStatus::Enable,
291328
}
292329
}
293330
}
@@ -587,6 +624,27 @@ impl LevelFilter {
587624
}
588625
}
589626

627+
/// An enum for enabling or disabling the different methods for logging.
628+
#[repr(u8)]
629+
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
630+
pub enum LoggerStatus {
631+
/// This method of logging is disabled
632+
Disable,
633+
/// This method of logging is enabled
634+
Enable,
635+
}
636+
637+
impl LoggerStatus {
638+
/// Converts an u8 into a Option<LoggerStatus>
639+
pub fn from_u8(value: u8) -> Option<LoggerStatus> {
640+
match value {
641+
0 => Some(Self::Disable),
642+
1 => Some(Self::Enable),
643+
_ => None,
644+
}
645+
}
646+
}
647+
590648
/// Taken from https://github.com/rust-lang/rust/blob/e100ec5bc7cd768ec17d75448b29c9ab4a39272b/library/core/src/slice/mod.rs#L1673-L1677
591649
///
592650
/// TODO replace with `split_array` feature in stdlib as soon as it's stabilized,

bios/stage-4/src/main.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::memory_descriptor::MemoryRegion;
55
use bootloader_api::{
6-
config::LevelFilter,
6+
config::{LevelFilter, LoggerStatus},
77
info::{FrameBufferInfo, PixelFormat},
88
};
99
use bootloader_x86_64_bios_common::{BiosFramebufferInfo, BiosInfo, E820MemoryRegion};
@@ -109,7 +109,12 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
109109
};
110110
let kernel = Kernel::parse(kernel_slice);
111111

112-
let framebuffer_info = init_logger(info.framebuffer, kernel.config.log_level);
112+
let framebuffer_info = init_logger(
113+
info.framebuffer,
114+
kernel.config.log_level,
115+
kernel.config.frame_buffer_logger_status,
116+
kernel.config.serial_logger_status,
117+
);
113118

114119
log::info!("4th Stage");
115120
log::info!("{info:x?}");
@@ -126,7 +131,12 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
126131
load_and_switch_to_kernel(kernel, frame_allocator, page_tables, system_info);
127132
}
128133

129-
fn init_logger(info: BiosFramebufferInfo, log_level: LevelFilter) -> FrameBufferInfo {
134+
fn init_logger(
135+
info: BiosFramebufferInfo,
136+
log_level: LevelFilter,
137+
frame_buffer_logger_status: LoggerStatus,
138+
serial_logger_status: LoggerStatus,
139+
) -> FrameBufferInfo {
130140
let framebuffer_info = FrameBufferInfo {
131141
byte_len: info.region.len.try_into().unwrap(),
132142
width: info.width.into(),
@@ -155,7 +165,13 @@ fn init_logger(info: BiosFramebufferInfo, log_level: LevelFilter) -> FrameBuffer
155165
)
156166
};
157167

158-
bootloader_x86_64_common::init_logger(framebuffer, framebuffer_info, log_level);
168+
bootloader_x86_64_common::init_logger(
169+
framebuffer,
170+
framebuffer_info,
171+
log_level,
172+
frame_buffer_logger_status,
173+
serial_logger_status,
174+
);
159175

160176
framebuffer_info
161177
}

common/src/lib.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use crate::legacy_memory_region::{LegacyFrameAllocator, LegacyMemoryRegion};
66
use bootloader_api::{
7-
config::{LevelFilter, Mapping},
7+
config::{LevelFilter, LoggerStatus, Mapping},
88
info::{FrameBuffer, FrameBufferInfo, MemoryRegion, TlsTemplate},
99
BootInfo, BootloaderConfig,
1010
};
@@ -33,13 +33,27 @@ pub mod level_4_entries;
3333
pub mod load_kernel;
3434
/// Provides a logger that logs output as text in various formats.
3535
pub mod logger;
36+
/// Provides a type that logs output as text to a Serial Being port.
3637
pub mod serial;
3738

3839
const PAGE_SIZE: u64 = 4096;
3940

4041
/// Initialize a text-based logger using the given pixel-based framebuffer as output.
41-
pub fn init_logger(framebuffer: &'static mut [u8], info: FrameBufferInfo, log_level: LevelFilter) {
42-
let logger = logger::LOGGER.get_or_init(move || logger::LockedLogger::new(framebuffer, info));
42+
pub fn init_logger(
43+
framebuffer: &'static mut [u8],
44+
info: FrameBufferInfo,
45+
log_level: LevelFilter,
46+
frame_buffer_logger_status: LoggerStatus,
47+
serial_logger_status: LoggerStatus,
48+
) {
49+
let logger = logger::LOGGER.get_or_init(move || {
50+
logger::LockedLogger::new(
51+
framebuffer,
52+
info,
53+
frame_buffer_logger_status,
54+
serial_logger_status,
55+
)
56+
});
4357
log::set_logger(logger).expect("logger already set");
4458
log::set_max_level(convert_level(log_level));
4559
log::info!("Framebuffer info: {:?}", info);

common/src/logger.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{framebuffer::FrameBufferWriter, serial::SerialPort};
2-
use bootloader_api::info::FrameBufferInfo;
2+
use bootloader_api::{config::LoggerStatus, info::FrameBufferInfo};
33
use conquer_once::spin::OnceCell;
44
use core::fmt::Write;
55
use spinning_top::Spinlock;
@@ -8,14 +8,26 @@ use spinning_top::Spinlock;
88
pub static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
99

1010
/// A [`FrameBufferWriter`] instance protected by a spinlock.
11-
pub struct LockedLogger(Spinlock<FrameBufferWriter>, Spinlock<SerialPort>);
11+
pub struct LockedLogger(
12+
Spinlock<FrameBufferWriter>,
13+
Spinlock<SerialPort>,
14+
LoggerStatus,
15+
LoggerStatus,
16+
);
1217

1318
impl LockedLogger {
1419
/// Create a new instance that logs to the given framebuffer.
15-
pub fn new(framebuffer: &'static mut [u8], info: FrameBufferInfo) -> Self {
20+
pub fn new(
21+
framebuffer: &'static mut [u8],
22+
info: FrameBufferInfo,
23+
frame_buffer_logger_status: LoggerStatus,
24+
serial_logger_status: LoggerStatus,
25+
) -> Self {
1626
LockedLogger(
1727
Spinlock::new(FrameBufferWriter::new(framebuffer, info)),
1828
Spinlock::new(SerialPort::new()),
29+
frame_buffer_logger_status,
30+
serial_logger_status,
1931
)
2032
}
2133

@@ -37,10 +49,14 @@ impl log::Log for LockedLogger {
3749
}
3850

3951
fn log(&self, record: &log::Record) {
40-
let mut logger = self.0.lock();
41-
let mut serial = self.1.lock();
42-
writeln!(logger, "{:5}: {}", record.level(), record.args()).unwrap();
43-
writeln!(serial, "{:5}: {}", record.level(), record.args()).unwrap();
52+
if self.2 == LoggerStatus::Enable {
53+
let mut logger = self.0.lock();
54+
writeln!(logger, "{:5}: {}", record.level(), record.args()).unwrap();
55+
}
56+
if self.3 == LoggerStatus::Enable {
57+
let mut serial = self.1.lock();
58+
writeln!(serial, "{:5}: {}", record.level(), record.args()).unwrap();
59+
}
4460
}
4561

4662
fn flush(&self) {}

uefi/src/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,13 @@ fn init_logger(st: &SystemTable<Boot>, config: BootloaderConfig) -> Option<RawFr
420420

421421
log::info!("UEFI boot");
422422

423-
bootloader_x86_64_common::init_logger(slice, info, config.log_level);
423+
bootloader_x86_64_common::init_logger(
424+
slice,
425+
info,
426+
config.log_level,
427+
config.frame_buffer_logger_status,
428+
config.serial_logger_status,
429+
);
424430

425431
Some(RawFrameBufferInfo {
426432
addr: PhysAddr::new(framebuffer.as_mut_ptr() as u64),

0 commit comments

Comments
 (0)