From 9646f7de8bb2b6d4c8726aeccf445bcf6f8254c4 Mon Sep 17 00:00:00 2001 From: August Date: Tue, 30 Sep 2025 15:17:41 -0400 Subject: [PATCH] Better deallocation --- src/kernel/boot/modules.rs | 2 -- src/kernel/memory.rs | 61 +++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/kernel/boot/modules.rs b/src/kernel/boot/modules.rs index 5a1675d..f636f2c 100644 --- a/src/kernel/boot/modules.rs +++ b/src/kernel/boot/modules.rs @@ -38,5 +38,3 @@ pub fn log_modules() { log_trace!("{log_msg}") } } - -// TODO: make initramfs a lazy static somehow? diff --git a/src/kernel/memory.rs b/src/kernel/memory.rs index cb7a3be..1dbac6b 100644 --- a/src/kernel/memory.rs +++ b/src/kernel/memory.rs @@ -1,10 +1,13 @@ // Copyright (c) 2025 shibedrill // SPDX-License-Identifier: GPL-3.0-or-later +use crate::boot::modules::MODULE_RESPONSE; +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 lazy_static::lazy_static; +use limine::response::MemoryMapResponse; use limine::{ memory_map::EntryType, request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest, PagingModeRequest}, @@ -12,25 +15,45 @@ use limine::{ }; use spin::Mutex; use talc::*; -use free_list::{FreeList, PageRange, PAGE_SIZE}; +use free_list::{AllocError, FreeList, PageRange, PAGE_SIZE}; pub extern crate alloc; static FREELIST: Mutex> = 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 fn deallocate_usable() -> Result<(), AllocError> { + init_statics(); + let mut bytes_deallocated: u64 = 0; + for entry in MEMMAP_RESPONSE.entries() { + if (entry.entry_type == EntryType::USABLE) | (entry.entry_type == EntryType::BOOTLOADER_RECLAIMABLE) { + deallocate(**entry)?; + bytes_deallocated += entry.length; + } + } + log_trace!("Deallocated 0x{:x} bytes", bytes_deallocated); + 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) + } +} + 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() { + 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 mmap_response.entries() { + for entry in MEMMAP_RESPONSE.entries() { log_msg.push_str(&format!( "{NEWLINE}\t0x{:x} bytes ({} pages) @ 0x{:x}: {}", entry.length, @@ -68,14 +91,6 @@ pub fn log_memory() { } EntryType::USABLE => { usable += entry.length; - let range = PageRange::from_start_len(entry.base as usize, entry.length as usize).expect("Could not convert map entry to range!"); - let dealloc_result = unsafe { - FREELIST.lock().deallocate(range) - }; - match dealloc_result { - Err(e) => log_warning!("Could not deallocate free memory at {}: {}", range, e), - Ok(_) => log_trace!("Deallocated free memory at {}", range), - } "usable" } _ => "unidentified", @@ -88,10 +103,14 @@ pub fn log_memory() { "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, ); + log_trace!("Deallocating available memory..."); + let _ = deallocate_usable(); + let free_bytes = { FREELIST.lock().free_space() }; + log_info!("Freelist: 0x{:x} bytes ({} pages)", free_bytes, free_bytes / PAGE_SIZE); + } else { panic!("Memory map contains no entries"); } - log_info!("Freelist info: 0x{:x} bytes of memory deallocated", FREELIST.lock().free_space()); } pub fn log_address() { @@ -110,6 +129,14 @@ pub fn log_address() { ); } +fn init_statics() { + let _ = EXECUTABLE_FILE_RESPONSE; + let _ = HHDM_RESPONSE; + let _ = MODULE_RESPONSE; + let _ = MEMMAP_RESPONSE; + crate::device::init_statics(); +} + #[used] #[unsafe(link_section = ".requests")] pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new();