//! 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 )] use core::sync::atomic::AtomicBool; use alloc::boxed::Box; use embedded_alloc::LlffHeap as Heap; use log::info; use crate::{ io::init_log, pci::{PciDeviceIterator, scan_pci_for_virtio_keyboard}, riscv::enable_supervisor_interrupt, scheduler::{SCHEDULER, idle}, user::{proc2, test}, vga::Vga, virtio::{ Virtqueue, input::{VirtioPciDriver, init_plic_pci}, }, virtual_fs::init_file_system, }; extern crate alloc; mod boot; mod critical_section; mod draw; mod fs; mod interrupt; mod io; 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; mod volatile; 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::() == core::mem::size_of::()); #[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."} // 1. Allouer de la mémoire statique alignée pour la queue static mut KBD_QUEUE: Virtqueue = unsafe { core::mem::zeroed() }; pub static mut KBD_DRIVER: Option = None; #[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(); SCHEDULER.lock().init(); init_file_system(); } info!("Hello World !"); // unsafe { Vga.draw_string(10, 10, "Hello World !", Color::WHITE, Color::BLACK) }; SCHEDULER.lock().create_process(Box::new(test), "proc1"); SCHEDULER.lock().create_process(Box::new(proc2), "proc2"); SCHEDULER .lock() .create_process_from_file("/usr/bin/test_pic"); enable_supervisor_interrupt(); for pci in PciDeviceIterator::new() { println!("{:x?}", pci.vendor_and_device_id()) } unsafe { let pci_info = scan_pci_for_virtio_keyboard().unwrap(); KBD_DRIVER = Some(VirtioPciDriver::new( pci_info.common_cfg, pci_info.notify_cfg, pci_info.isr_cfg, pci_info.notify_multiplier, &mut KBD_QUEUE, )); KBD_DRIVER.as_mut().unwrap().init(); init_plic_pci(34); } idle(); }