130 lines
3.8 KiB
Rust

#![no_main]
#![no_std]
#![allow(dead_code)]
#![allow(clippy::missing_safety_doc)]
#![feature(negative_impls)]
#![feature(panic_info_message)]
extern crate alloc;
extern crate core;
mod arch;
mod console;
mod fs;
mod io;
mod mem;
mod proc;
mod queue;
mod start;
mod string;
mod sync;
mod syscall;
mod trap;
use crate::{proc::cpu::cpuid, sync::mutex::Mutex};
use core::ffi::{c_char, CStr};
pub(crate) use crate::console::printf::{print, println};
pub static mut STARTED: bool = false;
pub static PANICKED: Mutex<bool> = Mutex::new(false);
/// Maximum number of processes
pub const NPROC: usize = 64;
/// Maximum number of CPUs
pub const NCPU: usize = 8;
/// Maximum number of open files per process
pub const NOFILE: usize = 16;
/// Maximum number of open files per system
pub const NFILE: usize = 100;
/// Maximum number of active inodes
pub const NINODE: usize = 50;
/// Maximum major device number
pub const NDEV: usize = 10;
/// Device number of file system root disk
pub const ROOTDEV: usize = 1;
/// Max exec arguments
pub const MAXARG: usize = 32;
/// Max num of blocks any FS op writes
pub const MAXOPBLOCKS: usize = 10;
/// Max data blocks in on-disk log
pub const LOGSIZE: usize = MAXOPBLOCKS * 3;
/// Size of disk block cache
pub const NBUF: usize = MAXOPBLOCKS * 3;
/// Size of file system in blocks
pub const FSSIZE: usize = 2000;
/// Maximum file path size
pub const MAXPATH: usize = 128;
pub unsafe fn main() -> ! {
if cpuid() == 0 {
console::consoleinit();
mem::kalloc::kinit();
println!("\nxv6 kernel is booting");
mem::virtual_memory::kvminit();
mem::virtual_memory::kvminithart();
proc::proc::procinit();
trap::trapinithart();
arch::riscv::plic::plicinit();
arch::riscv::plic::plicinithart();
io::bio::binit();
fs::iinit();
fs::file::fileinit();
fs::virtio_disk::virtio_disk_init();
proc::proc::userinit();
STARTED = true;
} else {
while !STARTED {
core::hint::spin_loop();
}
mem::virtual_memory::kvminithart();
trap::trapinithart();
arch::riscv::plic::plicinithart();
}
proc::proc::scheduler();
}
#[panic_handler]
fn panic_wrapper(panic_info: &core::panic::PanicInfo) -> ! {
if let Some(location) = panic_info.location() {
print!("kernel panic ({}): ", location.file());
} else {
print!("kernel panic: ");
}
if let Some(s) = panic_info.message() {
println!("{}", s);
} else if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
println!("{}", s);
} else if let Some(s) = panic_info.payload().downcast_ref::<&CStr>() {
println!("{:?}", s);
} else {
println!("could not recover error message");
}
println!("███████╗██╗ ██╗ ██████╗██╗ ██╗██╗██╗");
println!("██╔════╝██║ ██║██╔════╝██║ ██╔╝██║██║");
println!("█████╗ ██║ ██║██║ █████╔╝ ██║██║");
println!("██╔══╝ ██║ ██║██║ ██╔═██╗ ╚═╝╚═╝");
println!("██║ ╚██████╔╝╚██████╗██║ ██╗██╗██╗");
println!("╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝");
unsafe {
*crate::PANICKED.lock_spinning() = true;
// Quit QEMU for convenience.
crate::syscall::Syscall::Shutdown.call();
}
loop {
core::hint::spin_loop();
}
}
#[no_mangle]
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));
}