gila/src/kernel/memory.rs

161 lines
5.2 KiB
Rust

// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::constants::NEWLINE;
use crate::memory::alloc::boxed::Box;
use crate::{LOGGER, LogLevel, format, log_info, log_trace};
use alloc::string::String;
use core::pin::*;
use lazy_static::lazy_static;
use limine::{
memory_map::EntryType,
request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest, PagingModeRequest},
response::HhdmResponse,
};
use talc::*;
pub extern crate alloc;
pub struct FreeFrameBlockList {
head: Option<Pin<Box<FreeFrameBlock>>>,
}
impl FreeFrameBlockList {
pub fn push(&mut self) {
if let Some(inner) = &self.head {
} else {
}
}
}
// This structure represents a set of
// contiguous free page frames
pub struct FreeFrameBlock {
/// Number of contiguous 4KiB frames this block holds
num_frames: usize,
/// Pointer to the next block
next_block: Option<Pin<Box<FreeFrameBlock>>>,
}
impl FreeFrameBlock {
fn num_frames(&self) -> usize {
self.num_frames
}
fn next_block(&self) -> &Option<Pin<Box<FreeFrameBlock>>> {
&self.next_block
}
}
pub fn log_memory() {
// Panic if this is absent. It's needed to set up the GDT and paging
let mmap_response = MEMMAP_REQUEST
.get_response()
.expect("Bootloader did not supply memory map");
log_info!("Memory map received");
if !mmap_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 mmap_response.entries() {
log_msg.push_str(&format!(
"{NEWLINE}\t0x{:X} bytes @ 0x{:X}: {}",
entry.length,
entry.base,
match entry.entry_type {
EntryType::ACPI_NVS => {
hardware += entry.length;
"ACPI (reserved)"
}
EntryType::ACPI_RECLAIMABLE => {
reclaimable += entry.length;
"ACPI (reclaimable)"
}
EntryType::BAD_MEMORY => {
unusable += entry.length;
"damaged/unusable"
}
EntryType::BOOTLOADER_RECLAIMABLE => {
reclaimable += entry.length;
"bootloader (reclaimable)"
}
#[allow(unreachable_patterns, deprecated)]
EntryType::EXECUTABLE_AND_MODULES | EntryType::KERNEL_AND_MODULES => {
unusable += entry.length;
"executable & modules"
}
EntryType::FRAMEBUFFER => {
hardware += entry.length;
"framebuffer"
}
EntryType::RESERVED => {
unusable += entry.length;
"reserved"
}
EntryType::USABLE => {
usable += entry.length;
"usable"
}
_ => "unidentified",
}
));
}
log_trace!("{log_msg}");
let total = usable + reclaimable + hardware + unusable;
log_info!(
"Boot: Memory report: {NEWLINE}\tFree: 0x{usable:X}{NEWLINE}\tAvailable: 0x{reclaimable:X}{NEWLINE}\tUsable: 0x{:X}{NEWLINE}\tHardware: 0x{hardware:X}{NEWLINE}\tUnusable: 0x{unusable:X}{NEWLINE}\tTotal: 0x{total:X}",
usable + reclaimable,
);
} else {
panic!("Memory map contains no entries");
}
}
pub fn log_address() {
if let Some(resp) = ADDRESS_REQUEST.get_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()
);
}
#[used]
#[unsafe(link_section = ".requests")]
pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new();
#[used]
#[unsafe(link_section = ".requests")]
pub static ADDRESS_REQUEST: ExecutableAddressRequest =
limine::request::ExecutableAddressRequest::new();
#[used]
#[unsafe(link_section = ".requests")]
pub static MEMMAP_REQUEST: MemoryMapRequest = limine::request::MemoryMapRequest::new();
#[used]
#[unsafe(link_section = ".requests")]
pub static HHDM_REQUEST: HhdmRequest = limine::request::HhdmRequest::new();
lazy_static! {
pub static ref HHDM_RESPONSE: &'static HhdmResponse = HHDM_REQUEST
.get_response()
.expect("Did not get HHDM response from bootloader");
}
// TODO: 10kb kernel heap. Need to figure out how to make this less stupid...
static mut ARENA: [u8; 10000] = [0; 10000];
#[global_allocator]
static ALLOCATOR: Talck<spin::Mutex<()>, ClaimOnOom> =
Talc::new(unsafe { ClaimOnOom::new(Span::from_array(core::ptr::addr_of!(ARENA).cast_mut())) })
.lock();