From 56fc041f9da75242a28c65a6124bed3c7e796b6b Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Sun, 16 Jun 2024 16:03:25 +0800 Subject: [PATCH] feat: logging: parse loglevel from fdt --- kernel/src/entry.rs | 3 +++ kernel/src/logging.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/kernel/src/entry.rs b/kernel/src/entry.rs index 76319bf..5c8e70c 100644 --- a/kernel/src/entry.rs +++ b/kernel/src/entry.rs @@ -1,3 +1,4 @@ +use crate::logging::set_log_level; use crate::plat::console::{set_console, ConsoleDevice, ConsoleDriver, CONSOLE}; use crate::plat::lowlevel::{Hardware, LowLevel}; use crate::plat::timer::{Timer, TimerOps}; @@ -19,7 +20,9 @@ pub fn rust_main() -> ! { N_CPUS.store(fdt.cpus().count(), Ordering::Release); + set_log_level(&fdt); setup_console(&fdt); + info!("Kernel Started"); #[cfg(test)] diff --git a/kernel/src/logging.rs b/kernel/src/logging.rs index b87fce7..0197b63 100644 --- a/kernel/src/logging.rs +++ b/kernel/src/logging.rs @@ -2,6 +2,7 @@ use crate::plat::console::CONSOLE; use crate::{entry::HART_ID, plat::timer::CURRENT_TICK}; use core::fmt::Write; use core::sync::atomic::Ordering; +use fdt::Fdt; use log::{LevelFilter, Log, Metadata, Record}; #[macro_export] @@ -59,6 +60,35 @@ impl Log for SimpleLogger { pub fn init() { log::set_logger(&SimpleLogger).unwrap(); - // TODO: get log level from boot env + // Always log everything before the FDT is parsed log::set_max_level(LevelFilter::Trace); } + +pub fn set_log_level(fdt: &Fdt) { + const UNKNOWN_LEVEL: usize = 5; + + let log_level = fdt + .chosen() + .bootargs() + .map(|args| args.split_ascii_whitespace()) + .map(|args| args.filter(|arg| arg.starts_with("loglevel="))) + .map(|args| args.map(|arg| arg["loglevel=".len()..].parse::())) + .map(|args| args.last()) + .flatten() + .map(|level| level.unwrap_or(UNKNOWN_LEVEL)) + .unwrap_or(UNKNOWN_LEVEL); + + let level = match log_level { + 0 => LevelFilter::Error, + 1 => LevelFilter::Warn, + 2 => LevelFilter::Info, + 3 => LevelFilter::Debug, + 4 => LevelFilter::Trace, + #[cfg(debug_assertions)] + _ => LevelFilter::Trace, + #[cfg(not(debug_assertions))] + _ => LevelFilter::Error, + }; + + log::set_max_level(level); +}