Compare commits

..

3 Commits

Author SHA1 Message Date
315c8e33b7
Readability fixes 2025-09-30 20:12:02 -04:00
0a3d0147a8
Experimental MMIO freelist 2025-09-30 20:09:19 -04:00
ed4aef8978
Fixed wrong comment 2025-09-30 15:23:21 -04:00

View File

@ -6,6 +6,7 @@ use crate::boot::params::EXECUTABLE_FILE_RESPONSE;
use crate::constants::NEWLINE;
use crate::{LOGGER, LogLevel, format, log_info, log_trace};
use alloc::string::String;
use free_list::{AllocError, FreeList, PAGE_SIZE, PageRange};
use lazy_static::lazy_static;
use limine::response::MemoryMapResponse;
use limine::{
@ -15,14 +16,16 @@ use limine::{
};
use spin::Mutex;
use talc::*;
use free_list::{AllocError, FreeList, PageRange, PAGE_SIZE};
pub extern crate alloc;
static FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
static HW_FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
lazy_static! {
pub static ref MEMMAP_RESPONSE: &'static MemoryMapResponse = MEMMAP_REQUEST.get_response().expect("Bootloader did not supply memory map");
pub static ref MEMMAP_RESPONSE: &'static MemoryMapResponse = MEMMAP_REQUEST
.get_response()
.expect("Bootloader did not supply memory map");
}
pub fn deallocate_usable() -> Result<(), AllocError> {
@ -30,7 +33,9 @@ pub fn deallocate_usable() -> Result<(), AllocError> {
let mut any_error: Option<AllocError> = None;
let mut bytes_deallocated: u64 = 0;
for entry in MEMMAP_RESPONSE.entries() {
if (entry.entry_type == EntryType::USABLE) | (entry.entry_type == EntryType::BOOTLOADER_RECLAIMABLE) {
if (entry.entry_type == EntryType::USABLE)
| (entry.entry_type == EntryType::BOOTLOADER_RECLAIMABLE)
{
if let Err(error) = deallocate(**entry) {
any_error = Some(error);
}
@ -45,12 +50,66 @@ pub fn deallocate_usable() -> Result<(), AllocError> {
}
}
pub fn deallocate_hardware() -> Result<(), AllocError> {
let mut any_error: Option<AllocError> = None;
let mut bytes_deallocated: u64 = 0;
for entry in MEMMAP_RESPONSE.entries() {
if (entry.entry_type == EntryType::ACPI_NVS)
| (entry.entry_type == EntryType::RESERVED)
| (entry.entry_type == EntryType::FRAMEBUFFER)
{
if let Err(error) = {
// Special handling for regions that are too small
// TODO: fix
let adjusted_base = if (entry.length as usize) < PAGE_SIZE {
entry.base as usize - (PAGE_SIZE - entry.length as usize)
} else {
entry.base as usize
};
let adjusted_length = if (entry.length as usize) < PAGE_SIZE {
PAGE_SIZE
} else {
entry.length as usize
};
let range = PageRange::from_start_len(adjusted_base, adjusted_length);
log_trace!(
"Deallocating 0x{:x} @ 0x{:x} hardware reserved memory",
adjusted_length,
adjusted_base
);
match range {
Ok(range_inner) => unsafe { HW_FREELIST.lock().deallocate(range_inner) },
Err(err) => {
log_error!(
"Failed to convert range 0x{:x} @ 0x{:x}: {}",
adjusted_length,
adjusted_base,
err
);
Ok(())
}
}
} {
any_error = Some(error);
}
bytes_deallocated += entry.length;
}
}
log_trace!(
"Deallocated 0x{:x} bytes of hardware reserved memory",
bytes_deallocated
);
if let Some(error) = any_error {
Err(error)
} else {
Ok(())
}
}
pub fn deallocate(entry: limine::memory_map::Entry) -> Result<(), AllocError> {
let range = PageRange::from_start_len(entry.base as usize, entry.length as usize).expect("Could not convert map entry to range!");
unsafe {
FREELIST.lock().deallocate(range)
}
let range = PageRange::from_start_len(entry.base as usize, entry.length as usize)
.expect("Could not convert map entry to range!");
unsafe { FREELIST.lock().deallocate(range) }
}
pub fn log_memory() {
@ -112,9 +171,13 @@ pub fn log_memory() {
);
log_trace!("Deallocating available memory...");
let _ = deallocate_usable();
let _ = deallocate_hardware();
let free_bytes = { FREELIST.lock().free_space() };
log_info!("Freelist: 0x{:x} bytes ({} pages)", free_bytes, free_bytes / PAGE_SIZE);
log_info!(
"Freelist: 0x{:x} bytes ({} pages)",
free_bytes,
free_bytes / PAGE_SIZE
);
} else {
panic!("Memory map contains no entries");
}
@ -168,8 +231,8 @@ lazy_static! {
.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; 1000000] = [0; 1000000];
// 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> =