use crate::hw::uart::Uart; use crate::{KERNEL, board, mmu, platform, trap}; unsafe extern "C" { static _bss_start: u8; static _bss_end: u8; static _heap_start: u8; } pub fn init(uart: &Uart, boot_hart: usize) -> &'static mut mmu::PageTable { zero_bss(); let heap_start = unsafe { &_heap_start as *const u8 as usize }; mmu::init_allocator(heap_start); let kernel_pt = mmu::init_kernel_page_table(); let harts = crate::smp::probe_harts(); if boot_hart >= harts { crate::halt(uart, "boot hart outside the hart range"); } crate::smp::init( boot_hart, harts, mmu::virt_to_phys(kernel_pt as *const mmu::PageTable as usize), ); mmu::activate(kernel_pt); uart.write_str("k-os: MMU enabled (Sv39)\n"); match mmu::check_wx(kernel_pt) { Ok(code_pages) => { uart.write_str("k-os: W^X verified, "); uart.write_dec(code_pages); uart.write_str(" code pages\n"); } Err(v) => { let (what, va) = match v { mmu::page_table::WxViolation::WritableCode(va) => ("writable code", va), mmu::page_table::WxViolation::ExecutableData(va) => ("executable data", va), mmu::page_table::WxViolation::MappedHole(va) => ("mapped hole", va), mmu::page_table::WxViolation::LowerHalf(va) => ("lower-half mapping", va), }; uart.write_str("k-os: W^X violation: "); uart.write_str(what); uart.write_str(" at "); uart.write_hex(va); uart.put_char(b'\n'); crate::halt(uart, "kernel page table violates W^X"); } } trap::init(); crate::hw::timer::init(); crate::hw::plic::Plic::init(); uart.write_str("k-os: traps and timer initialized\n"); if board::USER_POOL_PAGES > domain::memory::frame::MAX_FRAMES { crate::halt(uart, "user pool larger than the frame table"); } let riscv_platform = platform::RiscVPlatform::new(kernel_pt as *const mmu::PageTable as usize, harts as u8); // SAFETY: `init_in_place` writes every field of the kernel. unsafe { KERNEL.init_with(|slot| { kernel::Kernel::init_in_place( slot, riscv_platform, types::address::PhysicalAddress::from_raw(board::USER_POOL_BASE), board::USER_POOL_PAGES, ) }); } kernel_pt } fn zero_bss() { unsafe { let start = &_bss_start as *const u8 as *mut u8; let end = &_bss_end as *const u8 as *mut u8; let len = end as usize - start as usize; core::ptr::write_bytes(start, 0, len); } }