//! Simple kernel for `SkavOS` //! //! This kernel is meant to be minimal and make easy the loading of other external modules pub mod device; pub mod interrupt; pub mod memory; pub mod screen; pub mod task; use bootloader_api::info::MemoryRegions; use bootloader_api::BootInfo; use log::info; use screen::buffer::WRITER; use x86_64::VirtAddr; use self::memory::paging::{PhysFrameAllocator, MAPPER}; use self::memory::vmm::VIRTUAL_MEMORY_MANAGER; use crate::kernel::screen::buffer::Buffer; /// Initializes the kernel pub fn init(boot_info: &'static mut BootInfo) { // Save the memory informations let level_4_table = VirtAddr::new( u64::from( boot_info .recursive_index .into_option() .unwrap_or_else(|| unreachable!("The physical memory has not been mapped")), ) * 0o0_010_010_010_010_000, // For the recursive mapping, the virtual address of the recursive index XXX is : 0oXXX_XXX_XXX_XXX_0000 ); let memory_regions: &'static MemoryRegions = &boot_info.memory_regions; let rsdp_addr = boot_info .rsdp_addr .into_option() .unwrap_or_else(|| unreachable!("The RSDP has no address")); // Initialization of the frame buffer let frame_buffer = boot_info .framebuffer .as_mut() .unwrap_or_else(|| unreachable!("It is assumed that there is a display")); WRITER.lock().set(Buffer::new(frame_buffer)).expect("Could not initialized the writer"); // Initialization of the memory mapper // SAFETY: The given `physical_memory_offset` is well-defined unsafe { MAPPER.lock().init(level_4_table); }; // Initialization of the virtual memory manager and the heap allocator let mut frame_allocator = PhysFrameAllocator::new(memory_regions); let last_beginning_addr = memory::init(&mut frame_allocator).expect("Cannot start the kernel if the heap allocator does not work"); // SAFETY: the asked args are well defined unsafe { VIRTUAL_MEMORY_MANAGER.lock().init(frame_allocator, last_beginning_addr); }; info!("Memory initialized"); // Initialization of the CPU interruptions interrupt::init(rsdp_addr); info!("Interruptions initialized"); // Initialization of the devices device::init(); info!("Devices initialized"); }