pub mod allocation; pub mod mapping; pub mod units; use allocation::page_alloc::FoundryOSFrameAllocator; use spin::{Mutex, Once}; use units::MemoryUnits::*; use x86_64::{ VirtAddr, registers::control::Cr3, structures::paging::{OffsetPageTable, PageTable}, }; pub const STACK_VIRTUAL_SPACE: usize = 0x5555_5555_0000; // start address of the memory space where we store allocated stacks pub const HEAP_VIRTUAL_SPACE: usize = 0x4444_4444_0000; // start address of heap allocated memory pub const HEAP_SIZE: usize = MiB(1).to_bytes(); pub static FRAME_ALLOCATOR: Once> = Once::new(); pub static OFFSET_PAGE_TABLE: Once> = Once::new(); /// Returns a mutable reference to the current level 4 page table. /// /// # Safety /// /// The caller must ensure that the level 4 page table is not modified /// simultaneously. The caller must also ensure that the physical memory offset /// is correct, to ensure that the correct virtual address is constructed. unsafe fn active_l4_table( physical_memory_offset: VirtAddr, ) -> &'static mut PageTable { let (level_4_frame, _) = Cr3::read(); let phys_addr = level_4_frame.start_address(); let virt = phys_addr.as_u64() + physical_memory_offset.as_u64(); unsafe { &mut *(virt as *mut PageTable) } } /// Initializes the `OffsetPageTable` for the current CPU architecture. /// /// # Safety /// /// This function must be called only once and should be called before any /// memory operations are performed that rely on virtual memory management. /// The provided `physical_memory_offset` must be accurate to ensure correct /// translation of physical addresses. /// /// # Parameters /// /// - `physical_memory_offset`: The offset to convert physical addresses to /// virtual addresses in the higher-half direct map. /// /// # Returns /// /// Returns an `OffsetPageTable` that allows for manipulation of the page /// tables for the current CPU architecture. pub fn init_page_table(physical_memory_offset: VirtAddr) { unsafe { let l4_table = active_l4_table(physical_memory_offset); let offset_table = OffsetPageTable::new(l4_table, physical_memory_offset); OFFSET_PAGE_TABLE.call_once(|| Mutex::new(offset_table)); } }