Skip to content

Commit

Permalink
Log level feature (rust-osdev#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
asensio-project authored Jan 3, 2023
1 parent 66c1218 commit fffa7ce
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 16 deletions.
1 change: 1 addition & 0 deletions api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fn main() {
(88, 9),
(97, 9),
(106, 9),
(115, 1),
];

let mut code = String::new();
Expand Down
59 changes: 56 additions & 3 deletions api/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ pub struct BootloaderConfig {
/// Configuration for the frame buffer that can be used by the kernel to display pixels
/// on the screen.
pub frame_buffer: FrameBuffer,

/// Configuration for changing the level of the filter of the messages that are shown in the
/// screen when booting. The default is 'Trace'.
pub log_level: LevelFilter,
}

impl BootloaderConfig {
Expand All @@ -35,7 +39,7 @@ impl BootloaderConfig {
0x3D,
];
#[doc(hidden)]
pub const SERIALIZED_LEN: usize = 115;
pub const SERIALIZED_LEN: usize = 116;

/// Creates a new default configuration with the following values:
///
Expand All @@ -48,6 +52,7 @@ impl BootloaderConfig {
version: ApiVersion::new_default(),
mappings: Mappings::new_default(),
frame_buffer: FrameBuffer::new_default(),
log_level: LevelFilter::Trace,
}
}

Expand All @@ -61,6 +66,7 @@ impl BootloaderConfig {
mappings,
kernel_stack_size,
frame_buffer,
log_level,
} = self;
let ApiVersion {
version_major,
Expand Down Expand Up @@ -133,13 +139,15 @@ impl BootloaderConfig {
},
);

concat_106_9(
let buf = concat_106_9(
buf,
match minimum_framebuffer_width {
Option::None => [0; 9],
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
},
)
);

concat_115_1(buf, (*log_level as u8).to_le_bytes())
}

/// Tries to deserialize a config byte array that was created using [`Self::serialize`].
Expand Down Expand Up @@ -252,6 +260,13 @@ impl BootloaderConfig {
(frame_buffer, s)
};

let (&log_level, s) = split_array_ref(s);
let log_level = LevelFilter::from_u8(u8::from_le_bytes(log_level));
let log_level = match log_level {
Option::Some(level) => level,
Option::None => return Err("log_level invalid"),
};

if !s.is_empty() {
return Err("unexpected rest");
}
Expand All @@ -261,6 +276,7 @@ impl BootloaderConfig {
kernel_stack_size: u64::from_le_bytes(kernel_stack_size),
mappings,
frame_buffer,
log_level,
})
}

Expand All @@ -271,6 +287,7 @@ impl BootloaderConfig {
mappings: Mappings::random(),
kernel_stack_size: rand::random(),
frame_buffer: FrameBuffer::random(),
log_level: LevelFilter::Trace,
}
}
}
Expand Down Expand Up @@ -534,6 +551,42 @@ impl Default for Mapping {
}
}

/// An enum representing the available verbosity level filters of the logger.
///
/// Based on
/// https://github.com/rust-lang/log/blob/dc32ab999f52805d5ce579b526bd9d9684c38d1a/src/lib.rs#L552-565
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LevelFilter {
/// A level lower than all log levels.
Off,
/// Corresponds to the `Error` log level.
Error,
/// Corresponds to the `Warn` log level.
Warn,
/// Corresponds to the `Info` log level.
Info,
/// Corresponds to the `Debug` log level.
Debug,
/// Corresponds to the `Trace` log level.
Trace,
}

impl LevelFilter {
/// Converts a u8 into a Option<LevelFilter>
pub fn from_u8(value: u8) -> Option<LevelFilter> {
match value {
0 => Some(Self::Off),
1 => Some(Self::Error),
2 => Some(Self::Warn),
3 => Some(Self::Info),
4 => Some(Self::Debug),
5 => Some(Self::Trace),
_ => None,
}
}
}

/// Taken from https://github.com/rust-lang/rust/blob/e100ec5bc7cd768ec17d75448b29c9ab4a39272b/library/core/src/slice/mod.rs#L1673-L1677
///
/// TODO replace with `split_array` feature in stdlib as soon as it's stabilized,
Expand Down
21 changes: 12 additions & 9 deletions bios/stage-4/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#![no_main]

use crate::memory_descriptor::MemoryRegion;
use bootloader_api::info::{FrameBufferInfo, PixelFormat};
use bootloader_api::{
config::LevelFilter,
info::{FrameBufferInfo, PixelFormat},
};
use bootloader_x86_64_bios_common::{BiosFramebufferInfo, BiosInfo, E820MemoryRegion};
use bootloader_x86_64_common::RawFrameBufferInfo;
use bootloader_x86_64_common::{
Expand All @@ -24,10 +27,6 @@ mod memory_descriptor;
#[no_mangle]
#[link_section = ".start"]
pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
let framebuffer_info = init_logger(info.framebuffer);
log::info!("4th Stage");
log::info!("{info:x?}");

let memory_map: &mut [E820MemoryRegion] = unsafe {
core::slice::from_raw_parts_mut(
info.memory_map_addr as *mut _,
Expand Down Expand Up @@ -102,8 +101,6 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
// it's mapped using `invlpg`, for efficiency.
x86_64::instructions::tlb::flush_all();

log::info!("BIOS boot");

let page_tables = create_page_tables(&mut frame_allocator);

let kernel_slice = {
Expand All @@ -112,6 +109,12 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
};
let kernel = Kernel::parse(kernel_slice);

let framebuffer_info = init_logger(info.framebuffer, kernel.config.log_level);

log::info!("4th Stage");
log::info!("{info:x?}");
log::info!("BIOS boot");

let system_info = SystemInfo {
framebuffer: Some(RawFrameBufferInfo {
addr: PhysAddr::new(info.framebuffer.region.start),
Expand All @@ -123,7 +126,7 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
load_and_switch_to_kernel(kernel, frame_allocator, page_tables, system_info);
}

fn init_logger(info: BiosFramebufferInfo) -> FrameBufferInfo {
fn init_logger(info: BiosFramebufferInfo, log_level: LevelFilter) -> FrameBufferInfo {
let framebuffer_info = FrameBufferInfo {
byte_len: info.region.len.try_into().unwrap(),
width: info.width.into(),
Expand Down Expand Up @@ -152,7 +155,7 @@ fn init_logger(info: BiosFramebufferInfo) -> FrameBufferInfo {
)
};

bootloader_x86_64_common::init_logger(framebuffer, framebuffer_info);
bootloader_x86_64_common::init_logger(framebuffer, framebuffer_info, log_level);

framebuffer_info
}
Expand Down
17 changes: 14 additions & 3 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use crate::legacy_memory_region::{LegacyFrameAllocator, LegacyMemoryRegion};
use bootloader_api::{
config::Mapping,
config::{LevelFilter, Mapping},
info::{FrameBuffer, FrameBufferInfo, MemoryRegion, TlsTemplate},
BootInfo, BootloaderConfig,
};
Expand Down Expand Up @@ -35,13 +35,24 @@ pub mod logger;
const PAGE_SIZE: u64 = 4096;

/// Initialize a text-based logger using the given pixel-based framebuffer as output.
pub fn init_logger(framebuffer: &'static mut [u8], info: FrameBufferInfo) {
pub fn init_logger(framebuffer: &'static mut [u8], info: FrameBufferInfo, log_level: LevelFilter) {
let logger = logger::LOGGER.get_or_init(move || logger::LockedLogger::new(framebuffer, info));
log::set_logger(logger).expect("logger already set");
log::set_max_level(log::LevelFilter::Trace);
log::set_max_level(convert_level(log_level));
log::info!("Framebuffer info: {:?}", info);
}

fn convert_level(level: LevelFilter) -> log::LevelFilter {
match level {
LevelFilter::Off => log::LevelFilter::Off,
LevelFilter::Error => log::LevelFilter::Error,
LevelFilter::Warn => log::LevelFilter::Warn,
LevelFilter::Info => log::LevelFilter::Info,
LevelFilter::Debug => log::LevelFilter::Debug,
LevelFilter::Trace => log::LevelFilter::Trace,
}
}

/// Required system information that should be queried from the BIOS or UEFI firmware.
#[derive(Debug, Copy, Clone)]
pub struct SystemInfo {
Expand Down
2 changes: 1 addition & 1 deletion uefi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ fn init_logger(st: &SystemTable<Boot>, config: BootloaderConfig) -> Option<RawFr

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

bootloader_x86_64_common::init_logger(slice, info);
bootloader_x86_64_common::init_logger(slice, info, config.log_level);

Some(RawFrameBufferInfo {
addr: PhysAddr::new(framebuffer.as_mut_ptr() as u64),
Expand Down

0 comments on commit fffa7ce

Please sign in to comment.