Files
k-os/crates/adapter-riscv/src/boot/hardware.rs

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);
}
}