yuesterdays problem solved, now i triple fault on write to CR3, fun

This commit is contained in:
Jack Halford 2018-03-15 17:16:01 +01:00
parent 8cf793260c
commit 5c2b5f723b
4 changed files with 39 additions and 31 deletions

View file

@ -2,6 +2,7 @@ use memory::{PAGE_SIZE, FrameAllocator};
use core::ptr::Unique; use core::ptr::Unique;
use x86::structures::paging::*; use x86::structures::paging::*;
use x86::instructions::tlb; use x86::instructions::tlb;
use x86::usize_conversions::usize_from;
use x86::*; use x86::*;
use super::paging::table::RecTable; use super::paging::table::RecTable;
@ -41,7 +42,7 @@ impl Mapper {
/// virtual page to physical frame translation /// virtual page to physical frame translation
pub fn translate_page(&self, page: Page) -> Option<PhysFrame> { pub fn translate_page(&self, page: Page) -> Option<PhysFrame> {
let p1 = self.p2().next_table(page.p2_index()); let p1 = self.p2().next_table(usize_from(u32::from(page.p2_index())));
let huge_page = || { let huge_page = || {
let p2_entry = &self.p2()[page.p2_index()]; let p2_entry = &self.p2()[page.p2_index()];
@ -64,8 +65,7 @@ impl Mapper {
where A: FrameAllocator where A: FrameAllocator
{ {
let p2 = self.p2_mut(); let p2 = self.p2_mut();
let p1 = p2.next_table_create(page.p2_index(), allocator); let p1 = p2.next_table_create(usize_from(u32::from(page.p2_index())), allocator);
assert!(p1[page.p1_index()].is_unused()); assert!(p1[page.p1_index()].is_unused());
p1[page.p1_index()].set(frame, flags | PageTableFlags::PRESENT); p1[page.p1_index()].set(frame, flags | PageTableFlags::PRESENT);
} }
@ -91,7 +91,7 @@ impl Mapper {
assert!(self.translate(page.start_address()).is_some()); assert!(self.translate(page.start_address()).is_some());
let p1 = self.p2_mut() let p1 = self.p2_mut()
.next_table_mut(page.p2_index()) .next_table_mut(usize_from(u32::from(page.p2_index())))
.expect("mapping code does not support huge pages"); .expect("mapping code does not support huge pages");
let frame = p1[page.p1_index()].pointed_frame().unwrap(); let frame = p1[page.p1_index()].pointed_frame().unwrap();
p1[page.p1_index()].set_unused(); p1[page.p1_index()].set_unused();

View file

@ -61,9 +61,23 @@ impl ActivePageTable {
} }
pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable { pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
let (p2_frame, cr3_flags) = Cr3::read(); let (p2_frame, cr3_flags) = Cr3::read();
let old_table = InactivePageTable { p2_frame }; let old_table = InactivePageTable { p2_frame };
unsafe { Cr3::write(new_table.p2_frame, cr3_flags); }
// unsafe { Cr3::write(new_table.p2_frame, cr3_flags); }
::console::regs();
flush!();
loop {}
unsafe { asm!("mov $0, %cr3" :: "r" (4096) : "memory"); }
// let addr = new_table.p2_frame.start_address();
// let value = addr.as_u32() | cr3_flags.bits();
// println!("value = {}", 0);
// flush!();
// loop {}
old_table old_table
} }
@ -81,16 +95,7 @@ impl InactivePageTable {
{ {
let table = temporary_page.map_table_frame(frame.clone(), active_table); let table = temporary_page.map_table_frame(frame.clone(), active_table);
// table.zero(); table.zero();
let iter = table.entries.iter_mut();
for entry in iter {
println!("entry = {:?}", entry as *const _);
// println!("entry = {:?}", entry.flags());
}
println!("frame = {:?}", frame);
flush!();
loop {}
// set up recursive mapping for the table // set up recursive mapping for the table
table[1023].set(frame.clone(), PageTableFlags::PRESENT | PageTableFlags::WRITABLE) table[1023].set(frame.clone(), PageTableFlags::PRESENT | PageTableFlags::WRITABLE)
} }
@ -103,14 +108,14 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
-> ActivePageTable -> ActivePageTable
where A: FrameAllocator where A: FrameAllocator
{ {
let mut temporary_page = TemporaryPage::new(Page { number: 0xcafe }, let mut temporary_page = TemporaryPage::new(Page{number: 0xcafe}, allocator);
allocator);
let mut active_table = unsafe { ActivePageTable::new() }; let mut active_table = unsafe { ActivePageTable::new() };
let mut new_table = { let mut new_table = {
let frame = allocator.allocate_frame().expect("no more frames"); let frame = allocator.allocate_frame().expect("no more frames");
InactivePageTable::new(frame, &mut active_table, &mut temporary_page) InactivePageTable::new(frame, &mut active_table, &mut temporary_page)
}; };
active_table.with(&mut new_table, &mut temporary_page, |mapper| { active_table.with(&mut new_table, &mut temporary_page, |mapper| {
// identity map the VGA text buffer // identity map the VGA text buffer
@ -146,12 +151,17 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
} }
}); });
let old_table = active_table.switch(new_table); let old_table = active_table.switch(new_table);
println!("check!");
flush!();
loop {}
let old_p2_page = Page::containing_address( let old_p2_page = Page::containing_address(
VirtAddr::new(old_table.p2_frame.start_address().as_u32())); VirtAddr::new(old_table.p2_frame.start_address().as_u32()));
active_table.unmap(old_p2_page, allocator); active_table.unmap(old_p2_page, allocator);
active_table active_table
} }

View file

@ -4,39 +4,39 @@ use x86::ux::*;
pub trait RecTable pub trait RecTable
{ {
fn next_table_address(&self, index: u10) -> Option<u32>; fn next_table_address(&self, index: usize) -> Option<u32>;
fn next_table(&self, index: u10) -> Option<&PageTable>; fn next_table(&self, index: usize) -> Option<&PageTable>;
fn next_table_mut(&mut self, index: u10) -> Option<&mut PageTable>; fn next_table_mut(&mut self, index: usize) -> Option<&mut PageTable>;
fn next_table_create<A: FrameAllocator>(&mut self, fn next_table_create<A: FrameAllocator>(&mut self,
index: u10, index: usize,
allocator: &mut A) allocator: &mut A)
-> &mut PageTable; -> &mut PageTable;
} }
impl RecTable for PageTable impl RecTable for PageTable
{ {
fn next_table_address(&self, index: u10) -> Option<u32> { fn next_table_address(&self, index: usize) -> Option<u32> {
let entry_flags = self[index].flags(); let entry_flags = self[index].flags();
if entry_flags.contains(PageTableFlags::PRESENT) && !entry_flags.contains(PageTableFlags::HUGE_PAGE) { if entry_flags.contains(PageTableFlags::PRESENT) && !entry_flags.contains(PageTableFlags::HUGE_PAGE) {
let table_address = self as *const _ as u32; let table_address = self as *const _ as usize;
Some(table_address << 10 | u32::from(index << 12)) Some((table_address << 10 | index << 12) as u32)
} else { } else {
None None
} }
} }
fn next_table(&self, index: u10) -> Option<&PageTable> { fn next_table(&self, index: usize) -> Option<&PageTable> {
self.next_table_address(index) self.next_table_address(index)
.map(|address| unsafe { &*(address as *const _) }) .map(|address| unsafe { &*(address as *const _) })
} }
fn next_table_mut(&mut self, index: u10) -> Option<&mut PageTable> { fn next_table_mut(&mut self, index: usize) -> Option<&mut PageTable> {
self.next_table_address(index) self.next_table_address(index)
.map(|address| unsafe { &mut *(address as *mut _) }) .map(|address| unsafe { &mut *(address as *mut _) })
} }
fn next_table_create<A>(&mut self, fn next_table_create<A>(&mut self,
index: u10, index: usize,
allocator: &mut A) -> &mut PageTable allocator: &mut A) -> &mut PageTable
where A: FrameAllocator where A: FrameAllocator
{ {

View file

@ -29,8 +29,6 @@ impl TemporaryPage {
// this kind of check should be done in a test routine // this kind of check should be done in a test routine
assert!(active_table.translate_page(self.page).is_some(), assert!(active_table.translate_page(self.page).is_some(),
"temporary page was not mapped"); "temporary page was not mapped");
println!("trans = {:?}", active_table.translate_page(self.page));
println!("page = {:?}", self.page.start_address());
self.page.start_address() self.page.start_address()
} }