diff --git a/kernel/aster-nix/src/console.rs b/kernel/aster-nix/src/console.rs index 3813a8588..5b66dbdad 100644 --- a/kernel/aster-nix/src/console.rs +++ b/kernel/aster-nix/src/console.rs @@ -18,6 +18,7 @@ impl Write for VirtioConsolesPrinter { } } +/// Prints the formatted arguments to the standard output. pub fn _print(args: Arguments) { VirtioConsolesPrinter.write_fmt(args).unwrap(); } diff --git a/kernel/aster-nix/src/device/tty/driver.rs b/kernel/aster-nix/src/device/tty/driver.rs index 9575df187..245ef65f3 100644 --- a/kernel/aster-nix/src/device/tty/driver.rs +++ b/kernel/aster-nix/src/device/tty/driver.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] -pub use ostd::arch::console; use ostd::mm::VmReader; use spin::Once; diff --git a/ostd/src/arch/x86/mod.rs b/ostd/src/arch/x86/mod.rs index bcb42c417..eaf47e60d 100644 --- a/ostd/src/arch/x86/mod.rs +++ b/ostd/src/arch/x86/mod.rs @@ -3,7 +3,6 @@ //! Platform-specific code for the x86 platform. pub mod boot; -pub mod console; pub(crate) mod cpu; pub mod device; pub(crate) mod ex_table; @@ -13,6 +12,7 @@ pub(crate) mod kernel; pub(crate) mod mm; pub(crate) mod pci; pub mod qemu; +pub mod serial; pub mod task; #[cfg(feature = "intel_tdx")] pub(crate) mod tdx_guest; @@ -31,7 +31,7 @@ use log::{info, warn}; pub(crate) fn before_all_init() { enable_common_cpu_features(); - console::init(); + serial::init(); } pub(crate) fn after_all_init() { @@ -46,7 +46,7 @@ pub(crate) fn after_all_init() { kernel::pic::enable(); } } - console::callback_init(); + serial::callback_init(); timer::init(); #[cfg(feature = "intel_tdx")] if !tdx_is_enabled() { diff --git a/ostd/src/arch/x86/console.rs b/ostd/src/arch/x86/serial.rs similarity index 97% rename from ostd/src/arch/x86/console.rs rename to ostd/src/arch/x86/serial.rs index 2c467f327..41b8aae0f 100644 --- a/ostd/src/arch/x86/console.rs +++ b/ostd/src/arch/x86/serial.rs @@ -15,7 +15,7 @@ use trapframe::TrapFrame; use super::{device::serial::SerialPort, kernel::IO_APIC}; use crate::{sync::SpinLock, trap::IrqLine}; -/// Prints the formatted arguments to the standard output. +/// Prints the formatted arguments to the standard output using the serial port. #[inline] pub fn print(args: fmt::Arguments) { Stdout.write_fmt(args).unwrap(); diff --git a/ostd/src/boot/mod.rs b/ostd/src/boot/mod.rs index d2aea974f..669e5fda0 100644 --- a/ostd/src/boot/mod.rs +++ b/ostd/src/boot/mod.rs @@ -158,7 +158,7 @@ fn run_ktests(test_whitelist: Option<&[&str]>, crate_whitelist: Option<&[&str]>) use ktest::runner::{run_ktests, KtestResult}; match run_ktests( - &crate::console::print, + &crate::console::early_print, fn_catch_unwind, test_whitelist.map(|s| s.iter().map(|s| s.to_string())), crate_whitelist, diff --git a/ostd/src/console.rs b/ostd/src/console.rs index 4c34fd1bb..d49944c58 100644 --- a/ostd/src/console.rs +++ b/ostd/src/console.rs @@ -5,23 +5,23 @@ use core::fmt::Arguments; /// Prints formatted arguments to the console. -pub fn print(args: Arguments) { - crate::arch::console::print(args); +pub fn early_print(args: Arguments) { + crate::arch::serial::print(args); } /// Prints to the console. #[macro_export] macro_rules! early_print { - ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::console::print(format_args!($fmt $(, $($arg)+)?)) - } + ($fmt: literal $(, $($arg: tt)+)?) => { + $crate::console::early_print(format_args!($fmt $(, $($arg)+)?)) + } } -/// Prints to the console, with a newline. +/// Prints to the console with a newline. #[macro_export] macro_rules! early_println { - () => { $crate::early_print!("\n") }; - ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) - } + () => { $crate::early_print!("\n") }; + ($fmt: literal $(, $($arg: tt)+)?) => { + $crate::console::early_print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) + } } diff --git a/ostd/src/logger.rs b/ostd/src/logger.rs index edf9403ec..28415fafa 100644 --- a/ostd/src/logger.rs +++ b/ostd/src/logger.rs @@ -1,6 +1,14 @@ // SPDX-License-Identifier: MPL-2.0 //! Logging support. +//! +//! Currently the logger prints the logs to the console. +//! +//! This module guarantees _atomicity_ under concurrency: messages are always +//! printed in their entirety without being mixed with messages generated +//! concurrently on other cores. +//! +//! IRQs are disabled while printing. So do not print long log messages. use alloc::format; @@ -48,6 +56,11 @@ impl log::Log for Logger { (timestamp, level, record_str) }; + // Use a global lock to prevent interleaving of log messages. + use crate::sync::SpinLock; + static RECORD_LOCK: SpinLock<()> = SpinLock::new(()); + let _lock = RECORD_LOCK.lock_irq_disabled(); + early_println!("{} {}: {}", timestamp, level, record_str); }