diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index 9c2cc37b..f541910e 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -1,4 +1,5 @@ -use memory::{PAGE_SIZE, Frame}; +pub use self::entry::*; +use memory::{PAGE_SIZE, Frame, FrameAllocator}; mod entry; mod table; @@ -38,14 +39,13 @@ impl Page { } } -pub fn translate(virtual_address: VirtualAddress) -> Option { +pub unsafe fn translate(virtual_address: VirtualAddress) -> Option { let offset = virtual_address % PAGE_SIZE; translate_page(Page::containing_address(virtual_address)) .map(|frame| frame.number * PAGE_SIZE + offset) } -fn translate_page(page: Page) -> Option { - use self::entry::HUGE_PAGE; +unsafe fn translate_page(page: Page) -> Option { let p3 = unsafe { &*table::P4 }.next_table(page.p4_index()); @@ -83,3 +83,15 @@ fn translate_page(page: Page) -> Option { .and_then(|p1| p1[page.p1_index()].pointed_frame()) .or_else(huge_page) } + +pub unsafe fn map_to(page: Page, frame: Frame, flags: EntryFlags, allocator: &mut A) + where A: FrameAllocator +{ + let p4 = unsafe { &mut *table::P4 }; + let mut p3 = p4.next_table_create(page.p4_index(), allocator); + let mut p2 = p3.next_table_create(page.p3_index(), allocator); + let mut p1 = p2.next_table_create(page.p2_index(), allocator); + + assert!(p1[page.p1_index()].is_unused()); + p1[page.p1_index()].set(frame, flags | PRESENT); +} diff --git a/src/memory/paging/table.rs b/src/memory/paging/table.rs index baad8523..b1a45d06 100644 --- a/src/memory/paging/table.rs +++ b/src/memory/paging/table.rs @@ -1,5 +1,6 @@ use memory::paging::entry::*; use memory::paging::ENTRY_COUNT; +use memory::FrameAllocator; use core::ops::{Index, IndexMut}; use core::marker::PhantomData; @@ -40,6 +41,22 @@ impl Table where L: HierachicalLevel self.next_table_address(index) .map(|t| unsafe { &mut *(t as *mut _) }) } + + pub fn next_table_create(&mut self, + index: usize, + allocator: &mut A) + -> &mut Table + where A: FrameAllocator + { + if self.next_table(index).is_none() { + assert!(!self.entries[index].flags().contains(HUGE_PAGE), + "mapping code does not support huge pages"); + let frame = allocator.allocate_frame().expect("no frames available"); + self.entries[index].set(frame, PRESENT | WRITABLE); + self.next_table_mut(index).unwrap().zero(); + } + self.next_table_mut(index).unwrap() + } } impl Index for Table where L: TableLevel