#![no_std] #![feature(abi_x86_interrupt)] #![warn( clippy::correctness, clippy::nursery, clippy::unnecessary_cast, clippy::all, clippy::suspicious, clippy::perf, rustdoc::missing_errors_doc, rustdoc::missing_panics_doc )] #![deny(clippy::mod_module_files)] extern crate alloc; use core::arch::asm; use limine::BaseRevision; use libk::drivers::kalloc::allocator::init_heap; use libk::prelude::*; use x86_64::VirtAddr; mod arch; /// Sets the base revision to the latest revision supported by the crate. /// See specification for further info. /// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler. #[used] // The .requests section allows limine to find the requests faster and more safely. #[unsafe(link_section = ".requests")] static BASE_REVISION: BaseRevision = BaseRevision::new(); #[panic_handler] fn rust_panic(_info: &core::panic::PanicInfo) -> ! { println!("Kernel panic: {}", _info); serial_println!("Kernel panic: {}", _info); hcf(); } pub fn hcf() -> ! { loop { unsafe { #[cfg(target_arch = "x86_64")] asm!("hlt"); #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] asm!("wfi"); #[cfg(target_arch = "loongarch64")] asm!("idle 0"); } } } pub fn boot() -> Result<(), &'static str> { if !BASE_REVISION.is_supported() { return Err("base revision not supported"); } use arch::x86_64::{gdt, interrupts, memmap, memory}; let memory_map = memmap::get_memory_map(); print_log!(" Initialising Serial... "); libk::drivers::io::serial::init()?; println_log!("[Success]"); print_log!(" Setting Up Global Descriptor Table... "); gdt::init(); println_log!("[Success]"); print_log!(" Setting Up Interrupt Descriptor Table... "); interrupts::init_idt(); println_log!("[Success]"); print_log!(" Setting Up Page Table... "); let mut frame_allocator = unsafe { memory::FoundryOSFrameAllocator::init(memory_map) }; println_log!("[Success]"); print_log!(" Initialising Memory Subsystem... "); let physical_memory_offset = VirtAddr::new(*memmap::PHYSICAL_MEMORY_OFFSET); let mut l4_table = unsafe { memory::init(physical_memory_offset) }; println_log!("[Success]"); print_log!(" Initialising Heap... "); if init_heap(&mut l4_table, &mut frame_allocator).is_err() { return Err("Failed to initialise heap: error"); } println_log!("[Success]"); print_log!(" Enabling Interrupts... "); x86_64::instructions::interrupts::enable(); println_log!("[Success]"); Ok(()) }