WIP: Create new page table for clone

This commit is contained in:
Jeremy Soller 2016-09-14 22:21:52 -06:00
parent c000820d72
commit b01a918556
3 changed files with 70 additions and 40 deletions

View file

@ -1,6 +1,7 @@
use arch::externs::memset;
use arch::paging::{ActivePageTable, Page, PageIter, VirtualAddress};
use arch::paging::{ActivePageTable, InactivePageTable, Page, PageIter, VirtualAddress};
use arch::paging::entry::EntryFlags;
use arch::paging::temporary_page::TemporaryPage;
#[derive(Debug)]
pub struct Memory {
@ -36,7 +37,7 @@ impl Memory {
Page::range_inclusive(start_page, end_page)
}
pub fn map(&mut self, flush: bool, clear: bool) {
fn map(&mut self, flush: bool, clear: bool) {
let mut active_table = unsafe { ActivePageTable::new() };
let mut flush_all = false;
@ -61,7 +62,7 @@ impl Memory {
}
}
pub fn unmap(&mut self, flush: bool) {
fn unmap(&mut self, flush: bool) {
let mut active_table = unsafe { ActivePageTable::new() };
let mut flush_all = false;
@ -80,6 +81,34 @@ impl Memory {
}
}
/// A complicated operation to move a piece of memory to a new page table
/// It also allows for changing the address at the same time
pub fn move_to(&mut self, new_start: VirtualAddress, new_table: &mut InactivePageTable, temporary_page: &mut TemporaryPage, flush: bool) {
let mut active_table = unsafe { ActivePageTable::new() };
let mut flush_all = false;
for page in self.pages() {
let frame = active_table.unmap_return(page);
active_table.with(new_table, temporary_page, |mapper| {
let new_page = Page::containing_address(VirtualAddress::new(page.start_address().get() - self.start.get() + new_start.get()));
mapper.map_to(new_page, frame, self.flags);
});
if flush {
//active_table.flush(page);
flush_all = true;
}
}
if flush_all {
active_table.flush_all();
}
self.start = new_start;
}
pub fn remap(&mut self, new_flags: EntryFlags, flush: bool) {
let mut active_table = unsafe { ActivePageTable::new() };
@ -101,36 +130,6 @@ impl Memory {
self.flags = new_flags;
}
pub fn replace(&mut self, new_start: VirtualAddress, flush: bool) {
let mut active_table = unsafe { ActivePageTable::new() };
let mut flush_all = false;
for page in self.pages() {
active_table.unmap(page);
if flush {
//active_table.flush(page);
flush_all = true;
}
}
self.start = new_start;
for page in self.pages() {
active_table.map(page, self.flags);
if flush {
//active_table.flush(page);
flush_all = true;
}
}
if flush_all {
active_table.flush_all();
}
}
pub fn resize(&mut self, new_size: usize, flush: bool, clear: bool) {
let mut active_table = unsafe { ActivePageTable::new() };