it compiles now with the new x86 lib, triple faults when setting temp page to zero though
This commit is contained in:
parent
0b38f701ed
commit
8cf793260c
8 changed files with 141 additions and 103 deletions
|
|
@ -178,7 +178,7 @@ pub fn acpi_info() -> Result <(), &'static str> {
|
||||||
pub fn regs() -> Result <(), &'static str> {
|
pub fn regs() -> Result <(), &'static str> {
|
||||||
use x86::registers::control::*;
|
use x86::registers::control::*;
|
||||||
println!("cr0={:#b}", Cr0::read());
|
println!("cr0={:#b}", Cr0::read());
|
||||||
println!("cr3={:#x}", Cr3::read());
|
println!("cr3={:?}", Cr3::read());
|
||||||
// TODO implement cr4 flags in `x86` module
|
// TODO implement cr4 flags in `x86` module
|
||||||
// println!("cr4={:#b}", Cr4::read());
|
// println!("cr4={:#b}", Cr4::read());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use memory::*;
|
use memory::*;
|
||||||
use multiboot2::{MemoryAreaIter, MemoryArea};
|
use multiboot2::{MemoryAreaIter, MemoryArea};
|
||||||
|
use x86::*;
|
||||||
|
|
||||||
pub struct AreaFrameAllocator {
|
pub struct AreaFrameAllocator {
|
||||||
next_free_frame: PhysFrame,
|
next_free_frame: PhysFrame,
|
||||||
|
|
@ -16,13 +17,17 @@ impl AreaFrameAllocator {
|
||||||
multiboot_start: usize, multiboot_end: usize,
|
multiboot_start: usize, multiboot_end: usize,
|
||||||
memory_areas: MemoryAreaIter) -> AreaFrameAllocator {
|
memory_areas: MemoryAreaIter) -> AreaFrameAllocator {
|
||||||
let mut allocator = AreaFrameAllocator {
|
let mut allocator = AreaFrameAllocator {
|
||||||
next_free_frame: PhysFrame::containing_address(0),
|
next_free_frame: PhysFrame { number: 0 },
|
||||||
current_area: None,
|
current_area: None,
|
||||||
areas: memory_areas,
|
areas: memory_areas,
|
||||||
kernel_start: PhysFrame::containing_address(kernel_start),
|
kernel_start: PhysFrame::containing_address(
|
||||||
kernel_end: PhysFrame::containing_address(kernel_end),
|
PhysAddr::new(kernel_start as u32)),
|
||||||
multiboot_start: PhysFrame::containing_address(multiboot_start),
|
kernel_end: PhysFrame::containing_address(
|
||||||
multiboot_end: PhysFrame::containing_address(multiboot_end),
|
PhysAddr::new(kernel_end as u32)),
|
||||||
|
multiboot_start: PhysFrame::containing_address(
|
||||||
|
PhysAddr::new(multiboot_start as u32)),
|
||||||
|
multiboot_end: PhysFrame::containing_address(
|
||||||
|
PhysAddr::new(multiboot_end as u32)),
|
||||||
};
|
};
|
||||||
allocator.choose_next_area();
|
allocator.choose_next_area();
|
||||||
allocator
|
allocator
|
||||||
|
|
@ -31,11 +36,12 @@ impl AreaFrameAllocator {
|
||||||
fn choose_next_area(&mut self) {
|
fn choose_next_area(&mut self) {
|
||||||
// get next area with free frames
|
// get next area with free frames
|
||||||
self.current_area = self.areas.clone().filter(|area| {
|
self.current_area = self.areas.clone().filter(|area| {
|
||||||
PhysFrame::containing_address(area.end_address()) >= self.next_free_frame
|
area.end_address() >= self.next_free_frame.start_address().as_u32() as usize
|
||||||
}).min_by_key(|area| area.start_address());
|
}).min_by_key(|area| area.start_address());
|
||||||
|
|
||||||
if let Some(area) = self.current_area {
|
if let Some(area) = self.current_area {
|
||||||
let start_frame = PhysFrame::containing_address(area.start_address());
|
let start_frame = PhysFrame::containing_address(
|
||||||
|
PhysAddr::new(area.start_address() as u32));
|
||||||
if self.next_free_frame < start_frame {
|
if self.next_free_frame < start_frame {
|
||||||
self.next_free_frame = start_frame;
|
self.next_free_frame = start_frame;
|
||||||
}
|
}
|
||||||
|
|
@ -45,9 +51,10 @@ impl AreaFrameAllocator {
|
||||||
|
|
||||||
impl FrameAllocator for AreaFrameAllocator {
|
impl FrameAllocator for AreaFrameAllocator {
|
||||||
fn allocate_frame(&mut self) -> Option<PhysFrame> {
|
fn allocate_frame(&mut self) -> Option<PhysFrame> {
|
||||||
if let Some(area) = self.current_arPhysea {
|
if let Some(area) = self.current_area {
|
||||||
let frame = PhysFrame { number: self.next_free_frame.number };
|
let frame = PhysFrame { number: self.next_free_frame.number };
|
||||||
let current_area_last_frame = PhysFrame::containing_address(area.end_address());
|
let current_area_last_frame = PhysFrame::containing_address(
|
||||||
|
PhysAddr::new(area.end_address() as u32));
|
||||||
if frame > current_area_last_frame {
|
if frame > current_area_last_frame {
|
||||||
// all frames are taken in this area
|
// all frames are taken in this area
|
||||||
self.choose_next_area();
|
self.choose_next_area();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ pub use self::area_allocator::*;
|
||||||
pub use self::heap_allocator::*;
|
pub use self::heap_allocator::*;
|
||||||
pub use self::paging::remap_the_kernel;
|
pub use self::paging::remap_the_kernel;
|
||||||
use multiboot2;
|
use multiboot2;
|
||||||
|
use x86::*;
|
||||||
use x86::structures::paging::*;
|
use x86::structures::paging::*;
|
||||||
|
|
||||||
pub trait FrameAllocator {
|
pub trait FrameAllocator {
|
||||||
|
|
@ -16,25 +16,6 @@ pub trait FrameAllocator {
|
||||||
fn deallocate_frame(&mut self, frame: PhysFrame);
|
fn deallocate_frame(&mut self, frame: PhysFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FrameIter {
|
|
||||||
start: PhysFrame,
|
|
||||||
end: PhysFrame,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for FrameIter {
|
|
||||||
type Item = PhysFrame;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<PhysFrame> {
|
|
||||||
if self.start <= self.end {
|
|
||||||
let frame = self.start.clone();
|
|
||||||
self.start.number += 1;
|
|
||||||
Some(frame)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// memory initialisation should only be called once
|
/// memory initialisation should only be called once
|
||||||
pub fn init(boot_info: &multiboot2::BootInformation) {
|
pub fn init(boot_info: &multiboot2::BootInformation) {
|
||||||
let elf_sections_tag = boot_info.elf_sections_tag().unwrap();
|
let elf_sections_tag = boot_info.elf_sections_tag().unwrap();
|
||||||
|
|
@ -59,10 +40,12 @@ pub fn init(boot_info: &multiboot2::BootInformation) {
|
||||||
boot_info);
|
boot_info);
|
||||||
use {HEAP_START, HEAP_SIZE};
|
use {HEAP_START, HEAP_SIZE};
|
||||||
|
|
||||||
let heap_start_page = Page::containing_address(HEAP_START);
|
let heap_start_page = Page::containing_address(
|
||||||
let heap_end_page = Page::containing_address(HEAP_START + HEAP_SIZE - 1);
|
VirtAddr::new(HEAP_START as u32));
|
||||||
|
let heap_end_page = Page::containing_address(
|
||||||
|
VirtAddr::new(HEAP_START as u32 + HEAP_SIZE as u32 - 1));
|
||||||
|
|
||||||
for page in Page::range_inclusive(heap_start_page, heap_end_page) {
|
for page in heap_start_page..heap_end_page {
|
||||||
active_table.map(page, PageTableFlags::WRITABLE, &mut frame_allocator);
|
active_table.map(page, PageTableFlags::WRITABLE, &mut frame_allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ use core::ptr::Unique;
|
||||||
use x86::structures::paging::*;
|
use x86::structures::paging::*;
|
||||||
use x86::instructions::tlb;
|
use x86::instructions::tlb;
|
||||||
use x86::*;
|
use x86::*;
|
||||||
//
|
use super::paging::table::RecTable;
|
||||||
|
|
||||||
// virtual address of recursively mapped P2
|
// virtual address of recursively mapped P2
|
||||||
// for protected mode non PAE
|
// for protected mode non PAE
|
||||||
// https://wiki.osdev.org/Page_Tables
|
// https://wiki.osdev.org/Page_Tables
|
||||||
|
|
@ -29,6 +30,7 @@ impl Mapper {
|
||||||
unsafe { self.p2.as_mut() }
|
unsafe { self.p2.as_mut() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// virtual addr to physical addr translation
|
||||||
pub fn translate(&self, virtual_address: VirtAddr) -> Option<PhysAddr>
|
pub fn translate(&self, virtual_address: VirtAddr) -> Option<PhysAddr>
|
||||||
{
|
{
|
||||||
let offset = virtual_address.as_u32() % PAGE_SIZE as u32;
|
let offset = virtual_address.as_u32() % PAGE_SIZE as u32;
|
||||||
|
|
@ -37,15 +39,26 @@ impl Mapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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()[page.p2_index()].points_to()
|
let huge_page = || {
|
||||||
.and_then(|paddr| PageTable::from(paddr));
|
let p2_entry = &self.p2()[page.p2_index()];
|
||||||
|
if let Some(start_frame) = p2_entry.pointed_frame() {
|
||||||
|
if p2_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
|
||||||
|
// TODO 4MiB alignment check
|
||||||
|
return Some(start_frame + u32::from(page.p1_index()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
p1.and_then()
|
p1.and_then(|p1| p1[page.p1_index()].pointed_frame())
|
||||||
|
.or_else(huge_page)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// map a virtual page to a physical frame in the page tables
|
||||||
pub fn map_to<A>(&mut self, page: Page, frame: PhysFrame, flags: PageTableFlags,
|
pub fn map_to<A>(&mut self, page: Page, frame: PhysFrame, flags: PageTableFlags,
|
||||||
allocator: &mut A)
|
allocator: &mut A)
|
||||||
where A: FrameAllocator
|
where A: FrameAllocator
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
// mod table;
|
mod table;
|
||||||
mod temporary_page;
|
mod temporary_page;
|
||||||
mod mapper;
|
mod mapper;
|
||||||
|
|
||||||
|
|
@ -9,28 +9,9 @@ use self::mapper::Mapper;
|
||||||
use self::temporary_page::TemporaryPage;
|
use self::temporary_page::TemporaryPage;
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
use multiboot2::BootInformation;
|
use multiboot2::BootInformation;
|
||||||
use x86;
|
use x86::*;
|
||||||
use x86::registers::control::Cr3;
|
use x86::registers::control::Cr3;
|
||||||
|
use x86::instructions::tlb;
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct PageIter {
|
|
||||||
start: Page,
|
|
||||||
end: Page,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for PageIter {
|
|
||||||
type Item = Page;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Page> {
|
|
||||||
if self.start <= self.end {
|
|
||||||
let page = self.start;
|
|
||||||
self.start.number += 1;
|
|
||||||
Some(page)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ActivePageTable {
|
pub struct ActivePageTable {
|
||||||
mapper: Mapper,
|
mapper: Mapper,
|
||||||
|
|
@ -63,14 +44,14 @@ impl ActivePageTable {
|
||||||
f: F)
|
f: F)
|
||||||
where F: FnOnce(&mut Mapper)
|
where F: FnOnce(&mut Mapper)
|
||||||
{
|
{
|
||||||
let (cr3_back, cr3flags_back) = Cr3::read();
|
let (cr3_back, _cr3flags_back) = Cr3::read();
|
||||||
|
|
||||||
// map temp page to current p2
|
// map temp page to current p2
|
||||||
let p2_table = temporary_page.map_table_frame(cr3_back.clone(), self);
|
let p2_table = temporary_page.map_table_frame(cr3_back.clone(), self);
|
||||||
|
|
||||||
// overwrite recursive map
|
// overwrite recursive map
|
||||||
self.p2_mut()[1023].set(table.p2_frame.clone(), PageTableFlags::PRESENT | PageTableFlags::WRITABLE);
|
self.p2_mut()[1023].set(table.p2_frame.clone(), PageTableFlags::PRESENT | PageTableFlags::WRITABLE);
|
||||||
x86::instructions::tlb::flush_all();
|
tlb::flush_all();
|
||||||
|
|
||||||
// execute f in the new context
|
// execute f in the new context
|
||||||
f(self);
|
f(self);
|
||||||
|
|
@ -80,17 +61,9 @@ 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 = PhysFrame::containing_address(Cr3::read() as usize);
|
let old_table = InactivePageTable { p2_frame };
|
||||||
|
unsafe { Cr3::write(new_table.p2_frame, cr3_flags); }
|
||||||
let old_table = InactivePageTable {
|
|
||||||
p2_frame,
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let frame = PhysFrame::containing_address(new_table.p2_frame.start_address());
|
|
||||||
Cr3::write(frame.start_address());
|
|
||||||
}
|
|
||||||
|
|
||||||
old_table
|
old_table
|
||||||
}
|
}
|
||||||
|
|
@ -103,13 +76,21 @@ pub struct InactivePageTable {
|
||||||
impl InactivePageTable {
|
impl InactivePageTable {
|
||||||
pub fn new(frame: PhysFrame,
|
pub fn new(frame: PhysFrame,
|
||||||
active_table: &mut ActivePageTable,
|
active_table: &mut ActivePageTable,
|
||||||
temporary_page: &mut TemporaryPage,
|
temporary_page: &mut TemporaryPage)
|
||||||
) -> InactivePageTable {
|
-> InactivePageTable {
|
||||||
{
|
{
|
||||||
let table = temporary_page.map_table_frame(frame.clone(),
|
let table = temporary_page.map_table_frame(frame.clone(), active_table);
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +114,7 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
|
||||||
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
|
||||||
let vga_buffer_frame = PhysFrame::containing_address(0xb8000);
|
let vga_buffer_frame = PhysFrame::containing_address(PhysAddr::new(0xb8000));
|
||||||
mapper.identity_map(vga_buffer_frame, PageTableFlags::WRITABLE, allocator);
|
mapper.identity_map(vga_buffer_frame, PageTableFlags::WRITABLE, allocator);
|
||||||
|
|
||||||
let elf_sections_tag = boot_info.elf_sections_tag()
|
let elf_sections_tag = boot_info.elf_sections_tag()
|
||||||
|
|
@ -146,24 +127,53 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
|
||||||
assert!(section.start_address() % PAGE_SIZE as u64 == 0,
|
assert!(section.start_address() % PAGE_SIZE as u64 == 0,
|
||||||
"sections need to be page aligned");
|
"sections need to be page aligned");
|
||||||
|
|
||||||
let flags = PageTableFlags::from_elf_section_flags(§ion);
|
let flags = elf_to_pagetable_flags(§ion.flags());
|
||||||
let start_frame = PhysFrame::containing_address(section.start_address() as usize);
|
let start_frame = PhysFrame::containing_address(
|
||||||
let end_frame = PhysFrame::containing_address(section.end_address() as usize - 1);
|
PhysAddr::new(section.start_address() as u32));
|
||||||
for frame in PhysFrame::range_inclusive(start_frame, end_frame) {
|
let end_frame = PhysFrame::containing_address(
|
||||||
|
PhysAddr::new(section.end_address() as u32 - 1));
|
||||||
|
for frame in start_frame..end_frame {
|
||||||
mapper.identity_map(frame, flags, allocator);
|
mapper.identity_map(frame, flags, allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let multiboot_start = PhysFrame::containing_address(boot_info.start_address());
|
let multiboot_start = PhysFrame::containing_address(
|
||||||
let multiboot_end = PhysFrame::containing_address(boot_info.end_address() - 1);
|
PhysAddr::new(boot_info.start_address() as u32));
|
||||||
for frame in PhysFrame::range_inclusive(multiboot_start, multiboot_end) {
|
let multiboot_end = PhysFrame::containing_address(
|
||||||
|
PhysAddr::new(boot_info.end_address() as u32 - 1));
|
||||||
|
for frame in multiboot_start..multiboot_end {
|
||||||
mapper.identity_map(frame, PageTableFlags::PRESENT, allocator);
|
mapper.identity_map(frame, PageTableFlags::PRESENT, allocator);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let old_table = active_table.switch(new_table);
|
let old_table = active_table.switch(new_table);
|
||||||
let old_p2_page = Page::containing_address(old_table.p2_frame.start_address());
|
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.unmap(old_p2_page, allocator);
|
||||||
active_table
|
active_table
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn elf_to_pagetable_flags(elf_flags: &multiboot2::ElfSectionFlags)
|
||||||
|
-> PageTableFlags
|
||||||
|
{
|
||||||
|
use multiboot2::ElfSectionFlags;
|
||||||
|
|
||||||
|
let mut flags = PageTableFlags::empty();
|
||||||
|
|
||||||
|
if elf_flags.contains(ElfSectionFlags::ALLOCATED) {
|
||||||
|
// section is loaded to memory
|
||||||
|
flags = flags | PageTableFlags::PRESENT;
|
||||||
|
}
|
||||||
|
if elf_flags.contains(ElfSectionFlags::WRITABLE) {
|
||||||
|
flags = flags | PageTableFlags::WRITABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LONG MODE STUFF
|
||||||
|
// if !elf_flags.contains(ELF_SECTION_EXECUTABLE) {
|
||||||
|
// flags = flags | PageTableFlags::NO_EXECUTE;
|
||||||
|
// }
|
||||||
|
|
||||||
|
flags
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,42 @@
|
||||||
use memory::*;
|
use memory::*;
|
||||||
use x86::structures::paging::*;
|
use x86::structures::paging::*;
|
||||||
|
use x86::ux::*;
|
||||||
|
|
||||||
|
pub trait RecTable
|
||||||
pub trait TableNext<A>
|
|
||||||
where A: FrameAllocator
|
|
||||||
{
|
{
|
||||||
fn next_table_address(&self, index: usize) -> Option<usize>;
|
fn next_table_address(&self, index: u10) -> Option<u32>;
|
||||||
fn next_table(&self, index: usize) -> Option<&PageTable>;
|
fn next_table(&self, index: u10) -> Option<&PageTable>;
|
||||||
fn next_table_mut(&mut self, index: usize) -> Option<&mut PageTable>;
|
fn next_table_mut(&mut self, index: u10) -> Option<&mut PageTable>;
|
||||||
fn next_table_create<A>(&mut self,
|
fn next_table_create<A: FrameAllocator>(&mut self,
|
||||||
index: usize,
|
index: u10,
|
||||||
allocator: &mut A) -> &mut PageTable;
|
allocator: &mut A)
|
||||||
|
-> &mut PageTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableNext<> for PageTable
|
impl RecTable for PageTable
|
||||||
{
|
{
|
||||||
|
fn next_table_address(&self, index: u10) -> 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))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_table(&self, index: u10) -> Option<&PageTable> {
|
||||||
|
self.next_table_address(index)
|
||||||
|
.map(|address| unsafe { &*(address as *const _) })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_table_mut(&mut self, index: u10) -> Option<&mut PageTable> {
|
||||||
|
self.next_table_address(index)
|
||||||
|
.map(|address| unsafe { &mut *(address as *mut _) })
|
||||||
|
}
|
||||||
|
|
||||||
fn next_table_create<A>(&mut self,
|
fn next_table_create<A>(&mut self,
|
||||||
index: usize,
|
index: u10,
|
||||||
allocator: &mut A) -> &mut PageTable
|
allocator: &mut A) -> &mut PageTable
|
||||||
where A: FrameAllocator
|
where A: FrameAllocator
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use x86::*;
|
||||||
use x86::structures::paging::*;
|
use x86::structures::paging::*;
|
||||||
|
|
||||||
pub struct TemporaryPage {
|
pub struct TemporaryPage {
|
||||||
page: Page,
|
pub page: Page,
|
||||||
allocator: TinyAllocator,
|
allocator: TinyAllocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,6 +26,11 @@ impl TemporaryPage {
|
||||||
assert!(active_table.translate_page(self.page).is_none(),
|
assert!(active_table.translate_page(self.page).is_none(),
|
||||||
"temporary page is already mapped");
|
"temporary page is already mapped");
|
||||||
active_table.map_to(self.page, frame, PageTableFlags::WRITABLE, &mut self.allocator);
|
active_table.map_to(self.page, frame, PageTableFlags::WRITABLE, &mut self.allocator);
|
||||||
|
// 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()
|
self.page.start_address()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,7 +45,7 @@ impl TemporaryPage {
|
||||||
frame: PhysFrame,
|
frame: PhysFrame,
|
||||||
active_table: &mut ActivePageTable)
|
active_table: &mut ActivePageTable)
|
||||||
-> &mut PageTable {
|
-> &mut PageTable {
|
||||||
unsafe { &mut *(self.map(frame, active_table) as *mut PageTable) }
|
unsafe { &mut *(self.map(frame, active_table).as_u32() as *mut PageTable) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit dc9eb5ceb8981848d95e0ddd7040fb86ec9999e3
|
Subproject commit eae470839b1ff232dbc4af5389e9a0b4fffe4b30
|
||||||
Loading…
Reference in a new issue