161 lines
5.2 KiB
Rust
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();
|