126 lines
3.1 KiB
Rust
126 lines
3.1 KiB
Rust
//! Kernel initialization and supervisor entry point.
|
|
//!
|
|
//! This module sets up the global heap, initializes core subsystems (VGA, filesystem,
|
|
//! scheduler, and logging), and starts initial processes.
|
|
#![no_std]
|
|
#![no_main]
|
|
// #![warn(clippy::pedantic)]
|
|
#![allow(static_mut_refs)]
|
|
#![feature(
|
|
riscv_ext_intrinsics,
|
|
str_from_raw_parts,
|
|
arbitrary_self_types_pointers,
|
|
derive_const,
|
|
const_cmp,
|
|
const_trait_impl,
|
|
trait_alias
|
|
)]
|
|
|
|
use core::sync::atomic::AtomicBool;
|
|
|
|
use alloc::boxed::Box;
|
|
use embedded_alloc::LlffHeap as Heap;
|
|
use log::info;
|
|
|
|
use crate::{
|
|
drivers::{keyboard::KBD_DRIVER, mouse::MOUSE_DRIVER},
|
|
io::init_log,
|
|
pci::scan_virtio_devices,
|
|
riscv::enable_supervisor_interrupt,
|
|
scheduler::{SCHEDULER, idle},
|
|
user::{proc2, test},
|
|
vga::Vga,
|
|
virtio::input::init_plic_pci,
|
|
virtual_fs::init_file_system,
|
|
};
|
|
|
|
extern crate alloc;
|
|
mod boot;
|
|
mod critical_section;
|
|
mod cursor;
|
|
mod data_structures;
|
|
mod draw;
|
|
mod drivers;
|
|
mod fs;
|
|
mod interrupt;
|
|
mod io;
|
|
mod keymap;
|
|
mod panic_handler;
|
|
mod pci;
|
|
mod process;
|
|
mod riscv;
|
|
mod scheduler;
|
|
mod sync;
|
|
mod syscall;
|
|
mod time;
|
|
mod tty;
|
|
mod uart;
|
|
mod user;
|
|
mod vga;
|
|
mod virtio;
|
|
mod virtual_console;
|
|
mod virtual_fs;
|
|
|
|
pub const HEAP_SIZE: usize = 1024 * 1024 * 32; // 32Mo RAM
|
|
#[global_allocator]
|
|
static HEAP: Heap = Heap::empty();
|
|
|
|
static HEAP_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
|
|
|
// Usize is assumed to be an u64 in the whole kernel
|
|
const _: () = assert!(core::mem::size_of::<usize>() == core::mem::size_of::<u64>());
|
|
#[cfg(not(target_endian = "little"))]
|
|
compile_error! {"This kernel implementation assume endianness is little-endian. Some memory access like PCI could not work in big-endian."}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub extern "C" fn supervisor_mode_entry() {
|
|
unsafe {
|
|
embedded_alloc::init!(HEAP, HEAP_SIZE);
|
|
HEAP_INITIALIZED.store(true, core::sync::atomic::Ordering::Relaxed);
|
|
init_log().unwrap();
|
|
Vga::init();
|
|
init_file_system();
|
|
SCHEDULER.lock().init();
|
|
}
|
|
|
|
info!("Hello World !");
|
|
// unsafe { Vga.draw_string(10, 10, "Hello World !", Color::WHITE, Color::BLACK) };
|
|
|
|
// let binding = Box::leak(Box::new(["coucou".as_bytes()]));
|
|
SCHEDULER
|
|
.lock()
|
|
.create_process(Box::new(test), "proc1", 0, core::ptr::null());
|
|
SCHEDULER
|
|
.lock()
|
|
.create_process(Box::new(proc2), "proc2", 0, core::ptr::null());
|
|
|
|
SCHEDULER
|
|
.lock()
|
|
.create_process_from_file("/usr/bin/test_pic", 0, core::ptr::null());
|
|
|
|
enable_supervisor_interrupt();
|
|
|
|
unsafe {
|
|
let (pci_keyboard, pci_mouse) = scan_virtio_devices();
|
|
let (pci_keyboard, pci_mouse) = (pci_keyboard.unwrap(), pci_mouse.unwrap());
|
|
|
|
KBD_DRIVER.init(
|
|
pci_keyboard.common_cfg,
|
|
pci_keyboard.notify_cfg,
|
|
pci_keyboard.isr_cfg,
|
|
pci_keyboard.notify_multiplier,
|
|
);
|
|
|
|
MOUSE_DRIVER.init(
|
|
pci_mouse.common_cfg,
|
|
pci_mouse.notify_cfg,
|
|
pci_mouse.isr_cfg,
|
|
pci_mouse.notify_multiplier,
|
|
);
|
|
|
|
init_plic_pci(pci_keyboard.irq);
|
|
init_plic_pci(pci_mouse.irq);
|
|
}
|
|
idle(0, core::ptr::null());
|
|
}
|