diff --git a/src/kxos-boot/src/main.rs b/src/kxos-boot/src/main.rs index b2999fa22..97a9738a4 100644 --- a/src/kxos-boot/src/main.rs +++ b/src/kxos-boot/src/main.rs @@ -4,7 +4,16 @@ use std::{ process::{Command, ExitStatus}, time::Duration, }; -const RUN_ARGS: &[&str] = &["--no-reboot", "-s"]; +const RUN_ARGS: &[&str] = &[ + "--no-reboot", + "-s", + "-device", + "isa-debug-exit,iobase=0xf4,iosize=0x04", + "-serial", + "stdio", + "-display", + "none", +]; const TEST_ARGS: &[&str] = &[ "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", diff --git a/src/kxos-frame/Cargo.toml b/src/kxos-frame/Cargo.toml index 314892b44..626597851 100644 --- a/src/kxos-frame/Cargo.toml +++ b/src/kxos-frame/Cargo.toml @@ -20,3 +20,9 @@ uart_16550 = "0.2.0" [dependencies.lazy_static] version = "1.0" features = ["spin_no_std"] + + +[features] +default = ["serial_print"] +serial_print = [] + diff --git a/src/kxos-frame/src/device/framebuffer.rs b/src/kxos-frame/src/device/framebuffer.rs index a862715b1..2e2f6c475 100644 --- a/src/kxos-frame/src/device/framebuffer.rs +++ b/src/kxos-frame/src/device/framebuffer.rs @@ -127,15 +127,15 @@ impl fmt::Write for Writer { /// Like the `print!` macro in the standard library, but prints to the VGA text buffer. #[macro_export] -macro_rules! print { +macro_rules! screen_print { ($($arg:tt)*) => ($crate::device::framebuffer::_print(format_args!($($arg)*))); } /// Like the `println!` macro in the standard library, but prints to the VGA text buffer. #[macro_export] -macro_rules! println { - () => ($crate::print!("\n")); - ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); +macro_rules! screen_println { + () => ($crate::screen_print!("\n")); + ($($arg:tt)*) => ($crate::screen_print!("{}\n", format_args!($($arg)*))); } /// Prints the given formatted string to the VGA text buffer diff --git a/src/kxos-frame/src/lib.rs b/src/kxos-frame/src/lib.rs index 5cf0476b1..1e1514889 100644 --- a/src/kxos-frame/src/lib.rs +++ b/src/kxos-frame/src/lib.rs @@ -42,6 +42,16 @@ use trap::{IrqCallbackHandle, IrqLine, TrapFrame}; static mut IRQ_CALLBACK_LIST: Vec = Vec::new(); +#[cfg(not(feature = "serial_print"))] +pub use crate::screen_print as print; +#[cfg(not(feature = "serial_print"))] +pub use crate::screen_println as println; + +#[cfg(feature = "serial_print")] +pub use crate::serial_print as print; +#[cfg(feature = "serial_print")] +pub use crate::serial_println as println; + pub fn init(boot_info: &'static mut BootInfo) { let siz = boot_info.framebuffer.as_ref().unwrap() as *const FrameBuffer as usize; device::init(boot_info.framebuffer.as_mut().unwrap()); diff --git a/src/kxos-frame/src/log.rs b/src/kxos-frame/src/log.rs index 4482967a0..556fafc76 100644 --- a/src/kxos-frame/src/log.rs +++ b/src/kxos-frame/src/log.rs @@ -3,7 +3,7 @@ use core::fmt::Arguments; /// Print log message /// This function should *NOT* be directly called. /// Instead, print logs with macros. -#[cfg(not(test))] +#[cfg(not(feature = "serial_print"))] #[doc(hidden)] pub fn log_print(args: Arguments) { use crate::device::framebuffer::WRITER; @@ -18,16 +18,18 @@ pub fn log_print(args: Arguments) { /// Print log message /// This function should *NOT* be directly called. /// Instead, print logs with macros. -#[cfg(test)] +#[cfg(feature = "serial_print")] #[doc(hidden)] pub fn log_print(args: Arguments) { use crate::device::serial::SERIAL; use core::fmt::Write; - - SERIAL - .lock() - .write_fmt(args) - .expect("Printing to serial failed"); + use x86_64::instructions::interrupts; + interrupts::without_interrupts(|| { + SERIAL + .lock() + .write_fmt(args) + .expect("Printing to serial failed"); + }); } /// This macro should not be directly called. diff --git a/src/kxos-frame/src/task/processor.rs b/src/kxos-frame/src/task/processor.rs index b4521dd3f..52d3509fb 100644 --- a/src/kxos-frame/src/task/processor.rs +++ b/src/kxos-frame/src/task/processor.rs @@ -50,14 +50,18 @@ pub(crate) fn get_idle_task_cx_ptr() -> *mut TaskContext { } /// call this function to switch to other task by using GLOBAL_SCHEDULER +pub fn schedule() { + switch_to_task(fetch_task().expect("no more task found")); +} + +/// call this function to switch to other task /// /// if current task is none, then it will use the default task context and it will not return to this function again /// /// if current task status is exit, then it will not add to the scheduler /// /// before context switch, current task will switch to the next task -pub fn schedule() { - let next_task = fetch_task().expect("no more task found"); +pub fn switch_to_task(next_task: Arc) { let current_task_option = current_task(); let next_task_cx_ptr = &next_task.inner_ctx() as *const TaskContext; let current_task: Arc; diff --git a/src/kxos-frame/src/task/task.rs b/src/kxos-frame/src/task/task.rs index d3ff4f701..3850aee5e 100644 --- a/src/kxos-frame/src/task/task.rs +++ b/src/kxos-frame/src/task/task.rs @@ -5,6 +5,7 @@ use lazy_static::lazy_static; use crate::cell::Cell; use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE}; +use crate::task::processor::switch_to_task; use crate::trap::{CalleeRegs, SyscallFrame, TrapFrame}; use crate::user::{syscall_switch_to_user_space, trap_switch_to_user_space, UserSpace}; use crate::vm::{VmAllocOptions, VmFrameVec}; @@ -177,9 +178,7 @@ impl Task { - size_of::(); let arc_self = Arc::new(result); - add_task(arc_self.clone()); - - schedule(); + switch_to_task(arc_self.clone()); Ok(arc_self) }