yuesterdays problem solved, now i triple fault on write to CR3, fun
This commit is contained in:
parent
8cf793260c
commit
5c2b5f723b
4 changed files with 39 additions and 31 deletions
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue