diff --git a/ostd/src/boot/kcmdline.rs b/kernel/src/kcmdline.rs similarity index 98% rename from ostd/src/boot/kcmdline.rs rename to kernel/src/kcmdline.rs index 517610b87..a4adaa3a7 100644 --- a/ostd/src/boot/kcmdline.rs +++ b/kernel/src/kcmdline.rs @@ -18,8 +18,6 @@ use alloc::{ vec::Vec, }; -use crate::early_println; - #[derive(PartialEq, Debug)] struct InitprocArgs { path: Option, @@ -116,7 +114,7 @@ impl From<&str> for KCmdlineArg { 1 => (arg_pattern[0], None), 2 => (arg_pattern[0], Some(arg_pattern[1])), _ => { - early_println!( + log::warn!( "[KCmdline] Unable to parse kernel argument {}, skip for now", arg ); @@ -129,7 +127,7 @@ impl From<&str> for KCmdlineArg { 1 => (None, entry_pattern[0]), 2 => (Some(entry_pattern[0]), entry_pattern[1]), _ => { - early_println!( + log::warn!( "[KCmdline] Unable to parse entry {} in argument {}, skip for now", entry, arg diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index c7f70df40..7e4698036 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -30,6 +30,7 @@ #![feature(trait_upcasting)] #![register_tool(component_access_control)] +use kcmdline::KCmdlineArg; use ostd::{ arch::qemu::{exit_qemu, QemuExitCode}, boot::boot_info, @@ -59,6 +60,7 @@ pub mod error; pub mod events; pub mod fs; pub mod ipc; +pub mod kcmdline; pub mod net; pub mod prelude; mod process; @@ -141,7 +143,7 @@ fn init_thread() { print_banner(); - let karg = &boot_info().kernel_cmdline; + let karg: KCmdlineArg = boot_info().kernel_cmdline.as_str().into(); let initproc = Process::spawn_user_process( karg.get_initproc_path().unwrap(), diff --git a/ostd/src/arch/x86/boot/multiboot/mod.rs b/ostd/src/arch/x86/boot/multiboot/mod.rs index 1d43b25ef..1523413a3 100644 --- a/ostd/src/arch/x86/boot/multiboot/mod.rs +++ b/ostd/src/arch/x86/boot/multiboot/mod.rs @@ -40,14 +40,10 @@ fn parse_kernel_commandline(mb1_info: &MultibootLegacyInfo) -> &str { if mb1_info.cmdline != 0 { // SAFETY: the command line is C-style zero-terminated string. unsafe { - let cstr = paddr_to_vaddr(mb1_info.cmdline as usize) as *const u8; - let mut len = 0; - while cstr.add(len).read() != 0 { - len += 1; - } + let cstr = paddr_to_vaddr(mb1_info.cmdline as usize) as *const i8; + let cstr = core::ffi::CStr::from_ptr(cstr); - cmdline = core::str::from_utf8(core::slice::from_raw_parts(cstr, len)) - .expect("cmdline is not a utf-8 string"); + cmdline = cstr.to_str().unwrap(); } } cmdline diff --git a/ostd/src/boot/mod.rs b/ostd/src/boot/mod.rs index d48ff12ce..346111643 100644 --- a/ostd/src/boot/mod.rs +++ b/ostd/src/boot/mod.rs @@ -6,7 +6,6 @@ //! 2. the routine booting into the actual kernel; //! 3. the routine booting the other processors in the SMP context. -pub mod kcmdline; pub mod memory_region; pub mod smp; @@ -15,7 +14,6 @@ use alloc::{ vec::Vec, }; -use kcmdline::KCmdlineArg; use memory_region::{MemoryRegion, MemoryRegionArray}; use spin::Once; @@ -24,7 +22,7 @@ pub struct BootInfo { /// The name of the bootloader. pub bootloader_name: String, /// The kernel command line arguments. - pub kernel_cmdline: KCmdlineArg, + pub kernel_cmdline: String, /// The initial ramfs raw bytes. pub initramfs: Option<&'static [u8]>, /// The framebuffer arguments. @@ -100,7 +98,7 @@ pub(crate) fn init() { INFO.call_once(|| BootInfo { bootloader_name: boot_time_info.bootloader_name.to_string(), - kernel_cmdline: boot_time_info.kernel_cmdline.into(), + kernel_cmdline: boot_time_info.kernel_cmdline.to_string(), initramfs: boot_time_info.initramfs, framebuffer_arg: boot_time_info.framebuffer_arg, memory_regions: boot_time_info.memory_regions.to_vec(), diff --git a/ostd/src/logger.rs b/ostd/src/logger.rs index 066b3d341..a941e2dc2 100644 --- a/ostd/src/logger.rs +++ b/ostd/src/logger.rs @@ -12,7 +12,7 @@ use core::str::FromStr; use log::{LevelFilter, Metadata, Record}; use spin::Once; -use crate::boot::{boot_info, kcmdline::ModuleArg}; +use crate::boot::BOOT_TIME_INFO; static LOGGER: Logger = Logger::new(); @@ -82,16 +82,15 @@ pub(crate) fn init() { } fn get_log_level() -> Option { - let module_args = boot_info().kernel_cmdline.get_module_args("ostd")?; + let kcmdline = BOOT_TIME_INFO.get().unwrap().kernel_cmdline; + + // Although OSTD is agnostic of the parsing of the kernel command line, + // the logger assumes that it follows the Linux kernel command line format. + // We search for the `ostd.log_level=ARGUMENT` pattern in string. + let value = kcmdline + .split(' ') + .find(|arg| arg.starts_with("ostd.log_level=")) + .map(|arg| arg.split('=').last().unwrap_or_default())?; - let value = { - let value = module_args.iter().find_map(|arg| match arg { - ModuleArg::KeyVal(name, value) if name.as_bytes() == "log_level".as_bytes() => { - Some(value) - } - _ => None, - })?; - value.as_c_str().to_str().ok()? - }; LevelFilter::from_str(value).ok() }