Pass kernel command line option to logger

This commit is contained in:
Yuke Peng
2024-06-28 13:29:28 +08:00
committed by Tate, Hongliang Tian
parent edc1412cc8
commit cf56bce57c
4 changed files with 46 additions and 19 deletions

View File

@ -11,6 +11,7 @@ GDB_TCP_PORT ?= 1234
INTEL_TDX ?= 0 INTEL_TDX ?= 0
RELEASE ?= 0 RELEASE ?= 0
RELEASE_LTO ?= 0 RELEASE_LTO ?= 0
LOG_LEVEL ?= error
SCHEME ?= "" SCHEME ?= ""
# End of global options. # End of global options.
@ -24,7 +25,7 @@ SYSCALL_TEST_DIR ?= /tmp
CARGO_OSDK := ~/.cargo/bin/cargo-osdk CARGO_OSDK := ~/.cargo/bin/cargo-osdk
CARGO_OSDK_ARGS := --target-arch=$(ARCH) CARGO_OSDK_ARGS := --target-arch=$(ARCH) --kcmd-args="ostd.log_level=$(LOG_LEVEL)"
ifeq ($(AUTO_TEST), syscall) ifeq ($(AUTO_TEST), syscall)
BUILD_SYSCALL_TEST := 1 BUILD_SYSCALL_TEST := 1

View File

@ -18,7 +18,7 @@ use alloc::{
vec::Vec, vec::Vec,
}; };
use log::warn; use crate::early_println;
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
struct InitprocArgs { struct InitprocArgs {
@ -116,7 +116,10 @@ impl From<&str> for KCmdlineArg {
1 => (arg_pattern[0], None), 1 => (arg_pattern[0], None),
2 => (arg_pattern[0], Some(arg_pattern[1])), 2 => (arg_pattern[0], Some(arg_pattern[1])),
_ => { _ => {
warn!("Unable to parse kernel argument {}, skip for now", arg); early_println!(
"[KCmdline] Unable to parse kernel argument {}, skip for now",
arg
);
continue; continue;
} }
}; };
@ -126,9 +129,10 @@ impl From<&str> for KCmdlineArg {
1 => (None, entry_pattern[0]), 1 => (None, entry_pattern[0]),
2 => (Some(entry_pattern[0]), entry_pattern[1]), 2 => (Some(entry_pattern[0]), entry_pattern[1]),
_ => { _ => {
warn!( early_println!(
"Unable to parse entry {} in argument {}, skip for now", "[KCmdline] Unable to parse entry {} in argument {}, skip for now",
entry, arg entry,
arg
); );
continue; continue;
} }

View File

@ -59,7 +59,6 @@ pub use self::{cpu::cpu_local::CpuLocal, error::Error, prelude::Result};
/// boot stage only global variables. /// boot stage only global variables.
pub fn init() { pub fn init() {
arch::before_all_init(); arch::before_all_init();
logger::init();
#[cfg(feature = "intel_tdx")] #[cfg(feature = "intel_tdx")]
let td_info = init_tdx().unwrap(); let td_info = init_tdx().unwrap();
@ -73,6 +72,7 @@ pub fn init() {
mm::heap_allocator::init(); mm::heap_allocator::init();
boot::init(); boot::init();
logger::init();
mm::page::allocator::init(); mm::page::allocator::init();
mm::kspace::init_boot_page_table(); mm::kspace::init_boot_page_table();

View File

@ -2,23 +2,20 @@
//! Logging support. //! Logging support.
use log::{Level, Metadata, Record}; use log::{LevelFilter, Metadata, Record};
use crate::early_println; use crate::{
boot::{kcmdline::ModuleArg, kernel_cmdline},
early_println,
};
const LOGGER: Logger = Logger {}; const LOGGER: Logger = Logger {};
/// The log level.
///
/// FIXME: The logs should be able to be read from files in the userspace,
/// and the log level should be configurable.
pub const INIT_LOG_LEVEL: Level = Level::Error;
struct Logger {} struct Logger {}
impl log::Log for Logger { impl log::Log for Logger {
fn enabled(&self, metadata: &Metadata) -> bool { fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= INIT_LOG_LEVEL metadata.level() <= log::max_level()
} }
fn log(&self, record: &Record) { fn log(&self, record: &Record) {
@ -30,8 +27,33 @@ impl log::Log for Logger {
fn flush(&self) {} fn flush(&self) {}
} }
/// Initialize the logger. Users should avoid using the log macros before this function is called.
pub(crate) fn init() { pub(crate) fn init() {
log::set_logger(&LOGGER) let level = get_log_level().unwrap_or(LevelFilter::Off);
.map(|()| log::set_max_level(INIT_LOG_LEVEL.to_level_filter()))
.unwrap(); log::set_max_level(level);
log::set_logger(&LOGGER).unwrap();
}
fn get_log_level() -> Option<LevelFilter> {
let module_args = kernel_cmdline().get_module_args("ostd")?;
let arg = module_args.iter().find(|arg| match arg {
ModuleArg::Arg(_) => false,
ModuleArg::KeyVal(name, _) => name.as_bytes() == "log_level".as_bytes(),
})?;
let ModuleArg::KeyVal(_, value) = arg else {
unreachable!()
};
let value = value.as_c_str().to_str().unwrap_or("off");
Some(match value {
"error" => LevelFilter::Error,
"warn" => LevelFilter::Warn,
"info" => LevelFilter::Info,
"debug" => LevelFilter::Debug,
"trace" => LevelFilter::Trace,
// Otherwise, OFF
_ => LevelFilter::Off,
})
} }