b26dc6de01
Probably incorrect PC was set.
149 lines
4.0 KiB
Rust
149 lines
4.0 KiB
Rust
#![no_std]
|
|
#![feature(abi_x86_interrupt)]
|
|
#![warn(
|
|
clippy::correctness,
|
|
clippy::nursery,
|
|
clippy::unnecessary_cast,
|
|
clippy::all,
|
|
clippy::suspicious,
|
|
clippy::perf,
|
|
rustdoc::missing_errors_doc,
|
|
rustdoc::missing_panics_doc
|
|
)]
|
|
|
|
extern crate alloc;
|
|
|
|
use crate::{
|
|
// TODO: Fix nesting under `arch`. A lot of code does not NEED to run on
|
|
// x86_64. Note that the panic handler does.
|
|
arch::x86_64::{
|
|
cpu::apic::enable_apic,
|
|
drivers::{
|
|
ascii::screensize_chars, framebuffer::display::screensize_px,
|
|
},
|
|
memory::{
|
|
FRAME_ALLOCATOR,
|
|
allocation::{
|
|
heap_alloc::init_heap, page_alloc::FoundryOSFrameAllocator,
|
|
},
|
|
init_page_table,
|
|
units::MemoryUnits,
|
|
},
|
|
},
|
|
prelude::*,
|
|
};
|
|
|
|
use arch::x86_64::memory::mapping;
|
|
use core::arch::asm;
|
|
use limine::BaseRevision;
|
|
use x86_64::VirtAddr;
|
|
|
|
pub mod arch;
|
|
pub mod resources;
|
|
#[allow(unused)] // We aren't using much of this right now.
|
|
pub mod std;
|
|
pub mod util;
|
|
|
|
pub mod prelude {
|
|
pub use crate::{
|
|
debug, debugln, eprint, eprintln, print, print_log, println,
|
|
println_log, serial_print, serial_println,
|
|
std::debug::_debug,
|
|
std::io::{_print, _print_err, _print_log, _serial_write},
|
|
};
|
|
}
|
|
|
|
/// 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.
|
|
#[unsafe(link_section = ".requests")]
|
|
static BASE_REVISION: BaseRevision = BaseRevision::new();
|
|
|
|
pub fn hcf() -> ! {
|
|
loop {
|
|
unsafe {
|
|
#[cfg(target_arch = "x86_64")]
|
|
asm!("hlt");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Panicking before this is initialised is unwise. We should probably extract
|
|
/// very early init into it's own function because Stack Traces may require
|
|
/// allocations etc.
|
|
pub fn boot() -> Result<(), &'static str> {
|
|
if !BASE_REVISION.is_supported() {
|
|
return Err("Base revision not supported");
|
|
}
|
|
|
|
use arch::x86_64::{gdt, interrupts};
|
|
|
|
let memory_map = mapping::get_memory_map();
|
|
|
|
print_log!(" Initialising Serial... ");
|
|
let res = arch::x86_64::drivers::serial::init();
|
|
serial_print!(" Initialising Serial... ");
|
|
if res.is_err() {
|
|
debugln!("[Not Detected]")
|
|
} else {
|
|
debugln!("[Success]");
|
|
}
|
|
|
|
debugln!(" Display...");
|
|
let dimensions = screensize_chars();
|
|
let dimensions2 = screensize_px();
|
|
debugln!(" => (px) : {}x{} ", dimensions2.0, dimensions2.1);
|
|
debugln!(" => (chars) : {}x{} ", dimensions.0, dimensions.1);
|
|
debugln!(" [Success]");
|
|
|
|
debug!(" Setting Up Global Descriptor Table... ");
|
|
gdt::init();
|
|
debugln!("[Success]");
|
|
|
|
debug!(" Setting Up Interrupt Descriptor Table... ");
|
|
interrupts::init_idt();
|
|
debugln!("[Success]");
|
|
|
|
debugln!(" Initialising Memory Subsystem... ");
|
|
let physical_memory_offset =
|
|
VirtAddr::new(*mapping::PHYSICAL_MEMORY_OFFSET);
|
|
init_page_table(physical_memory_offset);
|
|
FoundryOSFrameAllocator::init(memory_map);
|
|
let available_bytes =
|
|
FRAME_ALLOCATOR.get().unwrap().lock().available_memory();
|
|
debugln!(
|
|
" => Available Memory: {}",
|
|
MemoryUnits::from_bytes(available_bytes as usize)
|
|
);
|
|
|
|
debugln!("[Success]");
|
|
|
|
debugln!(" Initialising Heap... ");
|
|
if unsafe { init_heap() }.is_err() {
|
|
return Err("Failed to initialise heap: error");
|
|
}
|
|
debugln!(" [Success]");
|
|
|
|
// debug!(" Enabling PICs... ");
|
|
// interrupts::enable_pic();
|
|
// debugln!("[Success]");
|
|
|
|
debug!(" Disabling PICs... ");
|
|
interrupts::disable_pic();
|
|
debugln!("[Success]");
|
|
|
|
debug!(" Initialising APIC... ");
|
|
enable_apic();
|
|
debugln!("[Success]");
|
|
|
|
debug!(" Enabling Interrupts... ");
|
|
x86_64::instructions::interrupts::enable();
|
|
debugln!("[Success]");
|
|
|
|
Ok(())
|
|
}
|