diff --git a/Makefile b/Makefile index b03527c..2ba72ee 100644 --- a/Makefile +++ b/Makefile @@ -129,13 +129,13 @@ QEMUOPTS += -global virtio-mmio.force-legacy=false QEMUOPTS += -drive file=fs.img,if=none,format=raw,id=x0 QEMUOPTS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 -qemu: kernel/kernel fs.img +qemu: kernel fs.img $(QEMU) $(QEMUOPTS) .gdbinit: .gdbinit.tmpl-riscv sed "s/:1234/:$(GDBPORT)/" < $^ > $@ -qemu-gdb: kernel/kernel .gdbinit fs.img +qemu-gdb: kernel .gdbinit fs.img @echo "*** Now run 'gdb' in another window." 1>&2 $(QEMU) $(QEMUOPTS) -S $(QEMUGDB) diff --git a/kernel/rustkernel/Cargo.lock b/kernel/rustkernel/Cargo.lock index 9bafc96..516fd1e 100644 --- a/kernel/rustkernel/Cargo.lock +++ b/kernel/rustkernel/Cargo.lock @@ -2,29 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "format_no_std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6ab8bf81c8fc5032d2d3e651eb5fda8e225e278f1bc7abeda0a258b7ab5eff" - -[[package]] -name = "libc" -version = "0.2.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" - [[package]] name = "rustkernel" version = "0.1.0" -dependencies = [ - "arrayvec", - "format_no_std", - "libc", -] diff --git a/kernel/rustkernel/Cargo.toml b/kernel/rustkernel/Cargo.toml index d7718bc..25087f9 100644 --- a/kernel/rustkernel/Cargo.toml +++ b/kernel/rustkernel/Cargo.toml @@ -4,9 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -arrayvec = { version = "0.7.4", default-features = false } -format_no_std = "1.0.0" -libc = { version = "0.2.149", default-features = false } [lib] crate-type = ["staticlib"] diff --git a/kernel/rustkernel/src/console/mod.rs b/kernel/rustkernel/src/console/mod.rs index 4e79259..65314b6 100644 --- a/kernel/rustkernel/src/console/mod.rs +++ b/kernel/rustkernel/src/console/mod.rs @@ -46,6 +46,14 @@ impl Console { &mut self.buffer[i] } } +impl core::fmt::Write for Console { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + for b in s.as_bytes() { + Uart::write_byte_sync(*b); + } + core::fmt::Result::Ok(()) + } +} #[no_mangle] pub static cons: SpinMutex = SpinMutex::new(Console { diff --git a/kernel/rustkernel/src/console/printf.rs b/kernel/rustkernel/src/console/printf.rs index 1a17c51..cbd6d69 100644 --- a/kernel/rustkernel/src/console/printf.rs +++ b/kernel/rustkernel/src/console/printf.rs @@ -14,22 +14,13 @@ pub struct PrintLock { macro_rules! print { ($($arg:tt)*) => {{ + use core::fmt::Write; + // Still unsafe because static mut. let _guard = unsafe { $crate::console::printf::PRINT_LOCK.lock() }; - // Allocate a page of memory as the buffer and release it when we're done. - let buf = unsafe { $crate::mem::kalloc::kalloc() as *mut [u8; 4096] }; - - let s: &str = format_no_std::show( - unsafe { buf.as_mut() }.unwrap(), - format_args!($($arg)*), - ).unwrap(); - - for c in s.as_bytes() { - $crate::console::consputc(*c); - } - - unsafe { $crate::mem::kalloc::kfree(buf.cast()) }; + let mut cons = $crate::console::cons.lock(); + let _ = core::write!(cons.as_mut(), $($arg)*); }}; } pub(crate) use print; diff --git a/kernel/rustkernel/src/lib.rs b/kernel/rustkernel/src/lib.rs index 6ad6d00..574a2d0 100644 --- a/kernel/rustkernel/src/lib.rs +++ b/kernel/rustkernel/src/lib.rs @@ -3,6 +3,7 @@ #![allow(dead_code)] #![allow(clippy::missing_safety_doc)] #![feature(negative_impls)] +#![feature(panic_info_message)] extern crate alloc; extern crate core; @@ -88,20 +89,21 @@ pub unsafe extern "C" fn main() -> ! { #[panic_handler] fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! { - if let Some(s) = panic_info.payload().downcast_ref::<&str>() { - print!("kernel panic: {}\n", s); + if let Some(location) = panic_info.location() { + print!("kernel panic ({}): ", location.file()); } else { - print!("kernel panic\n"); + print!("kernel panic: "); } - // crate::printf::print!(" ______\n"); - // crate::printf::print!("< fuck!! >\n"); - // crate::printf::print!(" ------\n"); - // crate::printf::print!(" \\ ^__^ \n"); - // crate::printf::print!(" \\ (oo)\\_______\n"); - // crate::printf::print!(" (__)\\ )\\/\\\\\n"); - // crate::printf::print!(" ||----w |\n"); - // crate::printf::print!(" || ||\n"); + if let Some(s) = panic_info.message() { + print!("{}\n", s); + } else if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + print!("{}\n", s); + } else if let Some(s) = panic_info.payload().downcast_ref::<&CStr>() { + print!("{:?}\n", s); + } else { + print!("could not recover error message\n"); + } print!("███████╗██╗ ██╗ ██████╗██╗ ██╗██╗██╗\n"); print!("██╔════╝██║ ██║██╔════╝██║ ██╔╝██║██║\n"); @@ -110,7 +112,11 @@ fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! { print!("██║ ╚██████╔╝╚██████╗██║ ██╗██╗██╗\n"); print!("╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝\n"); - unsafe { crate::PANICKED = true }; + unsafe { + crate::PANICKED = true; + // Quit QEMU for convenience. + crate::syscall::Syscall::Shutdown.call(); + } loop { core::hint::spin_loop(); @@ -118,7 +124,8 @@ fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! { } #[no_mangle] -pub unsafe extern "C" fn panic(s: *const c_char) -> ! { - let s = CStr::from_ptr(s).to_str().unwrap_or("panic from c"); - panic!("{}", s); +pub unsafe extern "C" fn panic(_: *const c_char) -> ! { + panic!("panic from c"); + // let s = CStr::from_ptr(s).to_str().unwrap_or("panic from c"); + // panic!("{:?}", CStr::from_ptr(s)); } diff --git a/kernel/rustkernel/src/sync/spinmutex.rs b/kernel/rustkernel/src/sync/spinmutex.rs index fe99ec4..890546b 100644 --- a/kernel/rustkernel/src/sync/spinmutex.rs +++ b/kernel/rustkernel/src/sync/spinmutex.rs @@ -1,5 +1,6 @@ use core::{ cell::UnsafeCell, + convert::{AsMut, AsRef}, ops::{Deref, DerefMut, Drop}, sync::atomic::{AtomicBool, Ordering}, }; @@ -42,6 +43,16 @@ impl<'m, T> DerefMut for SpinMutexGuard<'m, T> { unsafe { &mut *self.mutex.inner.get() } } } +impl<'m, T> AsRef for SpinMutexGuard<'m, T> { + fn as_ref(&self) -> &T { + self.deref() + } +} +impl<'m, T> AsMut for SpinMutexGuard<'m, T> { + fn as_mut(&mut self) -> &mut T { + self.deref_mut() + } +} impl<'m, T> Drop for SpinMutexGuard<'m, T> { fn drop(&mut self) { unsafe { self.mutex.unlock() } diff --git a/kernel/rustkernel/src/syscall.rs b/kernel/rustkernel/src/syscall.rs index d11c5e0..0c4e10f 100644 --- a/kernel/rustkernel/src/syscall.rs +++ b/kernel/rustkernel/src/syscall.rs @@ -1,7 +1,7 @@ use crate::{ console::printf::print, proc::{self, myproc, sleep_lock}, - riscv::{Pagetable, memlayout::QEMU_POWER}, + riscv::{memlayout::QEMU_POWER, Pagetable}, string::strlen, }; use core::{mem::size_of, ptr::addr_of_mut};