139 lines
4.7 KiB
Rust
139 lines
4.7 KiB
Rust
// Copyright (c) 2025 shibedrill
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
const PAGE_SIZE: usize = 4096;
|
|
|
|
use crate::boot::modules::MODULE_RESPONSE;
|
|
use crate::boot::params::EXECUTABLE_FILE_RESPONSE;
|
|
use crate::{LOGGER, LogLevel, format};
|
|
use alloc::string::String;
|
|
|
|
use lazy_static::lazy_static;
|
|
use limine::request::{ExecutableAddressRequest, HhdmRepsonse, HhdmRequest};
|
|
use limine::request::{MemmapRequest, MemmapResponse};
|
|
use talc::*;
|
|
use x86_64::{PhysAddr, VirtAddr};
|
|
|
|
pub extern crate alloc;
|
|
|
|
pub mod paging;
|
|
|
|
pub fn phys_to_virt(phys: PhysAddr) -> VirtAddr {
|
|
VirtAddr::new(phys.as_u64() + HHDM_RESPONSE.offset)
|
|
}
|
|
|
|
lazy_static! {
|
|
pub static ref MEMMAP_RESPONSE: &'static MemmapResponse = MEMMAP_REQUEST
|
|
.response()
|
|
.expect("Bootloader did not supply memory map");
|
|
}
|
|
|
|
pub fn log_memory() {
|
|
if !MEMMAP_RESPONSE.entries().is_empty() {
|
|
let mut log_msg: String = String::from("Memory map:");
|
|
let mut usable: u64 = 0;
|
|
let mut reclaimable: u64 = 0;
|
|
let mut hardware: u64 = 0;
|
|
let mut unusable: u64 = 0;
|
|
for entry in MEMMAP_RESPONSE.entries() {
|
|
log_msg.push_str(&format!(
|
|
"\n\t0x{:x} bytes ({} pages) @ 0x{:x}: {}",
|
|
entry.length,
|
|
entry.length as usize / PAGE_SIZE,
|
|
entry.base,
|
|
match entry.type_ {
|
|
limine::memmap::MEMMAP_ACPI_NVS => {
|
|
hardware += entry.length;
|
|
"ACPI (reserved)"
|
|
}
|
|
limine::memmap::MEMMAP_ACPI_RECLAIMABLE => {
|
|
reclaimable += entry.length;
|
|
"ACPI (reclaimable)"
|
|
}
|
|
limine::memmap::MEMMAP_BAD_MEMORY => {
|
|
unusable += entry.length;
|
|
"damaged/unusable"
|
|
}
|
|
limine::memmap::MEMMAP_BOOTLOADER_RECLAIMABLE => {
|
|
reclaimable += entry.length;
|
|
"bootloader (reclaimable)"
|
|
}
|
|
limine::memmap::MEMMAP_EXECUTABLE_AND_MODULES => {
|
|
unusable += entry.length;
|
|
"executable & modules"
|
|
}
|
|
limine::memmap::MEMMAP_FRAMEBUFFER => {
|
|
hardware += entry.length;
|
|
"framebuffer"
|
|
}
|
|
limine::memmap::MEMMAP_RESERVED => {
|
|
unusable += entry.length;
|
|
"reserved"
|
|
}
|
|
limine::memmap::MEMMAP_USABLE => {
|
|
usable += entry.length;
|
|
"usable"
|
|
}
|
|
_ => "unidentified",
|
|
}
|
|
));
|
|
}
|
|
log_trace!("{log_msg}");
|
|
let total = usable + reclaimable + hardware + unusable;
|
|
log_info!(
|
|
"Memory report: \n\tFree: 0x{usable:x}\n\tAvailable: 0x{reclaimable:x}\n\tUsable: 0x{:x}\n\tHardware: 0x{hardware:x}\n\tUnusable: 0x{unusable:x}\n\tTotal: 0x{total:x}",
|
|
usable + reclaimable,
|
|
);
|
|
} else {
|
|
panic!("Memory map contains no entries");
|
|
}
|
|
}
|
|
|
|
pub fn log_address() {
|
|
if let Some(resp) = ADDRESS_REQUEST.response() {
|
|
log_info!("Kernel physical start address: 0x{:x}", resp.physical_base);
|
|
log_info!("Kernel virtual start address: 0x{:x}", resp.virtual_base);
|
|
} else {
|
|
log_warning!("No kernel address response provided.");
|
|
}
|
|
log_info!(
|
|
"Higher Half direct map offset: 0x{:x}",
|
|
HHDM_RESPONSE.offset
|
|
);
|
|
}
|
|
|
|
// Have to initialize all of these before reclaiming bootloader memory
|
|
pub fn init_statics() {
|
|
let _ = EXECUTABLE_FILE_RESPONSE;
|
|
let _ = HHDM_RESPONSE;
|
|
let _ = MODULE_RESPONSE;
|
|
let _ = MEMMAP_RESPONSE;
|
|
}
|
|
|
|
#[used]
|
|
#[unsafe(link_section = ".requests")]
|
|
pub static ADDRESS_REQUEST: ExecutableAddressRequest =
|
|
limine::request::ExecutableAddressRequest::new();
|
|
|
|
#[used]
|
|
#[unsafe(link_section = ".requests")]
|
|
pub static MEMMAP_REQUEST: MemmapRequest = limine::request::MemmapRequest::new();
|
|
|
|
#[used]
|
|
#[unsafe(link_section = ".requests")]
|
|
pub static HHDM_REQUEST: HhdmRequest = limine::request::HhdmRequest::new();
|
|
|
|
lazy_static! {
|
|
pub static ref HHDM_RESPONSE: &'static HhdmRepsonse = HHDM_REQUEST
|
|
.response()
|
|
.expect("Did not get HHDM response from bootloader");
|
|
}
|
|
|
|
// TODO: 1mb kernel heap. Need to figure out how to make this less stupid...
|
|
static mut ARENA: [u8; 100000] = [0; 100000];
|
|
|
|
#[global_allocator]
|
|
static ALLOCATOR: Talck<spin::Mutex<()>, ClaimOnOom> =
|
|
Talc::new(unsafe { ClaimOnOom::new(Span::from_array(core::ptr::addr_of!(ARENA).cast_mut())) })
|
|
.lock();
|