74 lines
2.1 KiB
Rust
74 lines
2.1 KiB
Rust
#![no_std]
|
|
#![feature(abi_x86_interrupt)]
|
|
|
|
extern crate alloc;
|
|
|
|
use core::arch::asm;
|
|
use limine::request::{RequestsEndMarker, RequestsStartMarker};
|
|
use limine::BaseRevision;
|
|
|
|
pub use lib_ascii::{print, print_log, println, println_log, WRITER};
|
|
pub use lib_serial::{serial_print, serial_println, serial_read};
|
|
use x86_64::structures::paging::Translate;
|
|
use x86_64::{PhysAddr, 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.
|
|
#[link_section = ".requests"]
|
|
static BASE_REVISION: BaseRevision = BaseRevision::new();
|
|
|
|
/// Define the stand and end markers for Limine requests.
|
|
#[used]
|
|
#[link_section = ".requests_start_marker"]
|
|
static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
|
|
#[used]
|
|
#[link_section = ".requests_end_marker"]
|
|
static _END_MARKER: RequestsEndMarker = RequestsEndMarker::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();
|
|
lib_serial::init()?;
|
|
gdt::init();
|
|
interrupts::init_idt();
|
|
|
|
let mut frame_allocator = unsafe { memory::FoundryOSFrameAllocator::init(memory_map) };
|
|
|
|
x86_64::instructions::interrupts::enable();
|
|
|
|
let physical_memory_offset = VirtAddr::new(*memmap::PHYSICAL_MEMORY_OFFSET);
|
|
let l4_table = unsafe { memory::init(physical_memory_offset) };
|
|
|
|
Ok(())
|
|
}
|