forked from AbleOS/ableos
117 lines
3.3 KiB
Rust
117 lines
3.3 KiB
Rust
mod memory;
|
|
|
|
use {
|
|
alloc::{boxed::Box, vec::Vec},
|
|
core::{
|
|
arch::{asm, global_asm},
|
|
fmt::Write,
|
|
},
|
|
sbi::system_reset::{system_reset, ResetReason, ResetType},
|
|
spin::{Mutex, Once},
|
|
uart_16550::MmioSerialPort,
|
|
};
|
|
|
|
use crate::{
|
|
allocator,
|
|
arch::riscv64::memory::{PageEntryFlags, PageSize, PageTable, PAGE_TABLE},
|
|
memory::PhysicalAddress,
|
|
};
|
|
|
|
global_asm!(include_str!("entry.s"));
|
|
global_asm!(include_str!("memory_regions.s"));
|
|
|
|
pub const PAGE_SIZE: usize = 4096;
|
|
|
|
extern "C" {
|
|
static TEXT_START: PhysicalAddress;
|
|
static TEXT_END: PhysicalAddress;
|
|
|
|
static RODATA_START: PhysicalAddress;
|
|
static RODATA_END: PhysicalAddress;
|
|
|
|
static DATA_START: PhysicalAddress;
|
|
static DATA_END: PhysicalAddress;
|
|
|
|
static SDATA_START: PhysicalAddress;
|
|
static SDATA_END: PhysicalAddress;
|
|
|
|
static BSS_START: PhysicalAddress;
|
|
static BSS_END: PhysicalAddress;
|
|
|
|
static INITIAL_KERNEL_HEAP_START: PhysicalAddress;
|
|
static INITIAL_KERNEL_HEAP_SIZE: usize;
|
|
|
|
static USABLE_MEMORY_START: PhysicalAddress;
|
|
static USABLE_MEMORY_SIZE: usize;
|
|
}
|
|
|
|
pub static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
|
|
|
|
#[no_mangle]
|
|
unsafe extern "C" fn _kernel_start() -> ! {
|
|
SERIAL_CONSOLE.call_once(|| Mutex::new(unsafe { MmioSerialPort::new(0x1000_0000) }));
|
|
crate::logger::init().expect("failed to set logger");
|
|
log::info!("Initialising AKern {}", crate::VERSION);
|
|
|
|
allocator::init(
|
|
INITIAL_KERNEL_HEAP_START.as_mut_ptr::<u8>(),
|
|
INITIAL_KERNEL_HEAP_SIZE,
|
|
);
|
|
memory::init(USABLE_MEMORY_START.into(), USABLE_MEMORY_SIZE / PAGE_SIZE);
|
|
|
|
let mut page_table_addr = PAGE_TABLE.get().unwrap().lock();
|
|
let mut page_table = page_table_addr.as_mut_ptr::<PageTable>().as_mut().unwrap();
|
|
|
|
// Map text (executable) section
|
|
page_table.identity_map_range(TEXT_START, TEXT_END, PageEntryFlags::ReadExecute);
|
|
// Map rodata section
|
|
page_table.identity_map_range(RODATA_START, RODATA_END, PageEntryFlags::Read);
|
|
// Map data section
|
|
page_table.identity_map_range(DATA_START, DATA_END, PageEntryFlags::ReadWrite);
|
|
// Map sdata section
|
|
page_table.identity_map_range(SDATA_START, SDATA_END, PageEntryFlags::ReadWrite);
|
|
// Map bss section (includes stack and initial kernel heap)
|
|
page_table.identity_map_range(BSS_START, BSS_END, PageEntryFlags::ReadWrite);
|
|
// Map usable memory range (as rw so not executable)
|
|
page_table.identity_map_range(
|
|
USABLE_MEMORY_START,
|
|
USABLE_MEMORY_START + USABLE_MEMORY_SIZE.into(),
|
|
PageEntryFlags::ReadWrite,
|
|
);
|
|
// Map Uart so we can continue using serial
|
|
page_table.identity_map(
|
|
0x1000_0000_usize.into(),
|
|
PageEntryFlags::ReadWrite,
|
|
PageSize::Size4KiB,
|
|
);
|
|
|
|
let table_ppn = page_table_addr.as_addr() as usize >> 12;
|
|
let satp_value = 8 << 60 | table_ppn;
|
|
log::info!("Enabling MMU");
|
|
|
|
asm!(
|
|
"csrw satp, {}",
|
|
"sfence.vma",
|
|
in(reg) satp_value,
|
|
);
|
|
|
|
crate::kmain::kmain("baka=9", Vec::new());
|
|
}
|
|
|
|
/// Spin loop
|
|
pub fn spin_loop() -> ! {
|
|
loop {
|
|
unsafe { asm!("wfi") }
|
|
}
|
|
}
|
|
|
|
pub fn hardware_random_u64() -> u64 {
|
|
0
|
|
}
|
|
|
|
pub fn register_dump() {}
|
|
|
|
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
|
SERIAL_CONSOLE.get().unwrap().lock().write_fmt(args)
|
|
}
|