diff --git a/Cargo.lock b/Cargo.lock index f6a9fce..9f8eee0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,6 +16,12 @@ dependencies = [ "spinning_top", ] +[[package]] +name = "align-address" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6c08a67736554282858203cd9b7ff53cf55f54c34e85689962748a350cbf0" + [[package]] name = "autocfg" version = "1.5.0" @@ -101,6 +107,17 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" +[[package]] +name = "free-list" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "810f338a4ef98f319a279c9199f35d7ec366c6002ca6a8f18fdcc94cfef9afab" +dependencies = [ + "align-address", + "smallvec", + "x86_64", +] + [[package]] name = "gila" version = "0.3.1" @@ -109,6 +126,7 @@ dependencies = [ "enumflags2", "fdt", "flagset", + "free-list", "intbits", "lazy_static", "limine", @@ -264,6 +282,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + [[package]] name = "spin" version = "0.9.8" diff --git a/Cargo.toml b/Cargo.toml index b1b2a90..0bfe55d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ acpi = { version = "6.0.1", optional = true } enumflags2 = "0.7.12" fdt = { git = "https://github.com/repnop/fdt", version = "0.2.0-alpha1", optional = true } flagset = "0.4.7" +free-list = { version = "0.3.1", features = ["x86_64"] } intbits = "0.2.0" lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] } limine = "0.5.0" diff --git a/src/kernel/arch/x86_64/paging.rs b/src/kernel/arch/x86_64/paging.rs index f15bd82..b937168 100644 --- a/src/kernel/arch/x86_64/paging.rs +++ b/src/kernel/arch/x86_64/paging.rs @@ -26,7 +26,7 @@ pub fn get_mappings() { } ); let pml4_addr = Cr3::read_raw().0.start_address(); - log_info!("Page Map Level 4 Address: 0x{:X}", pml4_addr.as_u64()); + log_info!("Page Map Level 4 Address: 0x{:x}", pml4_addr.as_u64()); log_info!( "Page-Level Write-Through: {}", Cr3::read().1.contains(Cr3Flags::PAGE_LEVEL_WRITETHROUGH) diff --git a/src/kernel/interrupt/mod.rs b/src/kernel/interrupt/mod.rs index 52fda8b..6875d83 100644 --- a/src/kernel/interrupt/mod.rs +++ b/src/kernel/interrupt/mod.rs @@ -8,5 +8,5 @@ pub fn double_fault(info: String) -> ! { } pub fn page_fault(addr: usize, info: String) -> ! { - panic!("Page fault at 0x{:X}: {}", addr, info); + panic!("Page fault at 0x{:x}: {}", addr, info); } diff --git a/src/kernel/memory.rs b/src/kernel/memory.rs index 62343de..cb7a3be 100644 --- a/src/kernel/memory.rs +++ b/src/kernel/memory.rs @@ -2,49 +2,21 @@ // 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 spin::Mutex; use talc::*; +use free_list::{FreeList, PageRange, PAGE_SIZE}; pub extern crate alloc; -pub struct FreeFrameBlockList { - head: Option>>, -} - -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>>, -} - -impl FreeFrameBlock { - fn num_frames(&self) -> usize { - self.num_frames - } - fn next_block(&self) -> &Option>> { - &self.next_block - } -} +static FREELIST: Mutex> = Mutex::new(FreeList::<32>::new()); pub fn log_memory() { // Panic if this is absent. It's needed to set up the GDT and paging @@ -60,8 +32,9 @@ pub fn log_memory() { let mut unusable: u64 = 0; for entry in mmap_response.entries() { log_msg.push_str(&format!( - "{NEWLINE}\t0x{:X} bytes @ 0x{:X}: {}", + "{NEWLINE}\t0x{:x} bytes ({} pages) @ 0x{:x}: {}", entry.length, + entry.length as usize / PAGE_SIZE, entry.base, match entry.entry_type { EntryType::ACPI_NVS => { @@ -95,6 +68,14 @@ 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", @@ -104,26 +85,27 @@ pub fn log_memory() { 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}", + "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"); } + log_info!("Freelist info: 0x{:x} bytes of memory deallocated", FREELIST.lock().free_space()); } pub fn log_address() { if let Some(resp) = ADDRESS_REQUEST.get_response() { log_info!( - "Kernel physical start address: 0x{:X}", + "Kernel physical start address: 0x{:x}", resp.physical_base() ); - log_info!("Kernel virtual start address: 0x{:X}", resp.virtual_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}", + "Higher Half direct map offset: 0x{:x}", HHDM_RESPONSE.offset() ); } @@ -152,7 +134,7 @@ lazy_static! { } // TODO: 10kb kernel heap. Need to figure out how to make this less stupid... -static mut ARENA: [u8; 10000] = [0; 10000]; +static mut ARENA: [u8; 1000000] = [0; 1000000]; #[global_allocator] static ALLOCATOR: Talck, ClaimOnOom> =