82 lines
2.7 KiB
Rust
82 lines
2.7 KiB
Rust
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);
|
|
}
|
|
}
|