diff --git a/src/memory.rs b/src/memory.rs index 97fb34a7..be4433b8 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,4 +1,23 @@ -use x86_64::{structures::paging::PageTable, PhysAddr, VirtAddr}; +use x86_64::{ + structures::paging::{MappedPageTable, MapperAllSizes, PageTable, PhysFrame}, + PhysAddr, VirtAddr, +}; + +/// Initialize a new MappedPageTable. +/// +/// This function is unsafe because the caller must guarantee that the +/// complete physical memory is mapped to virtual memory at the passed +/// `physical_memory_offset`. Also, this function must be only called once +/// to avoid aliasing `&mut` references (which is undefined behavior). +pub unsafe fn init(physical_memory_offset: u64) -> impl MapperAllSizes { + let level_4_table = active_level_4_table(physical_memory_offset); + let phys_to_virt = move |frame: PhysFrame| -> *mut PageTable { + let phys = frame.start_address().as_u64(); + let virt = VirtAddr::new(phys + physical_memory_offset); + virt.as_mut_ptr() + }; + MappedPageTable::new(level_4_table, phys_to_virt) +} /// Returns a mutable reference to the active level 4 table. /// @@ -6,7 +25,7 @@ use x86_64::{structures::paging::PageTable, PhysAddr, VirtAddr}; /// complete physical memory is mapped to virtual memory at the passed /// `physical_memory_offset`. Also, this function must be only called once /// to avoid aliasing `&mut` references (which is undefined behavior). -pub unsafe fn active_level_4_table(physical_memory_offset: u64) -> &'static mut PageTable { +unsafe fn active_level_4_table(physical_memory_offset: u64) -> &'static mut PageTable { use x86_64::{registers::control::Cr3, VirtAddr}; let (level_4_table_frame, _) = Cr3::read();