diff --git a/src/lib.rs b/src/lib.rs index 34debc4f..5974e73c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ pub mod gdt; pub mod interrupts; +pub mod memory; pub mod serial; pub mod vga_buffer; diff --git a/src/memory.rs b/src/memory.rs new file mode 100644 index 00000000..a7c85335 --- /dev/null +++ b/src/memory.rs @@ -0,0 +1,19 @@ +use x86_64::structures::paging::PageTable; + +/// Returns a mutable reference to the active level 4 table. +/// +/// 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 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(); + + let phys = level_4_table_frame.start_address(); + let virt = VirtAddr::new(phys.as_u64() + physical_memory_offset); + let page_table_ptr: *mut PageTable = virt.as_mut_ptr(); + + &mut *page_table_ptr // unsafe +}