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 x86::structures::paging::*;
use x86::instructions::tlb;
use x86::usize_conversions::usize_from;
use x86::*;
use super::paging::table::RecTable;
@ -41,7 +42,7 @@ impl Mapper {
/// virtual page to physical frame translation
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 p2_entry = &self.p2()[page.p2_index()];
@ -55,7 +56,7 @@ impl Mapper {
};
p1.and_then(|p1| p1[page.p1_index()].pointed_frame())
.or_else(huge_page)
.or_else(huge_page)
}
/// map a virtual page to a physical frame in the page tables
@ -64,8 +65,7 @@ impl Mapper {
where A: FrameAllocator
{
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());
p1[page.p1_index()].set(frame, flags | PageTableFlags::PRESENT);
}
@ -91,7 +91,7 @@ impl Mapper {
assert!(self.translate(page.start_address()).is_some());
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");
let frame = p1[page.p1_index()].pointed_frame().unwrap();
p1[page.p1_index()].set_unused();

View file

@ -61,9 +61,23 @@ impl ActivePageTable {
}
pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
let (p2_frame, cr3_flags) = Cr3::read();
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
}
@ -81,16 +95,7 @@ impl InactivePageTable {
{
let table = temporary_page.map_table_frame(frame.clone(), active_table);
// 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 {}
table.zero();
// set up recursive mapping for the table
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
where A: FrameAllocator
{
let mut temporary_page = TemporaryPage::new(Page { number: 0xcafe },
allocator);
let mut temporary_page = TemporaryPage::new(Page{number: 0xcafe}, allocator);
let mut active_table = unsafe { ActivePageTable::new() };
let mut new_table = {
let frame = allocator.allocate_frame().expect("no more frames");
InactivePageTable::new(frame, &mut active_table, &mut temporary_page)
};
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
// 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);
println!("check!");
flush!();
loop {}
let old_p2_page = Page::containing_address(
VirtAddr::new(old_table.p2_frame.start_address().as_u32()));
active_table.unmap(old_p2_page, allocator);
active_table
}

View file

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

View file

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