Move `paging` mod to `arch`, as Redox did.

master
WangRunji 7 years ago
parent 5b91db9d76
commit 77703442e7

@ -1,9 +0,0 @@
use x86_64;
pub fn enable() {
unsafe{ x86_64::instructions::interrupts::enable(); }
}
pub fn disable() {
unsafe{ x86_64::instructions::interrupts::disable(); }
}

@ -0,0 +1,11 @@
use x86_64;
#[inline(always)]
pub unsafe fn enable() {
x86_64::instructions::interrupts::enable();
}
#[inline(always)]
pub unsafe fn disable() {
x86_64::instructions::interrupts::disable();
}

@ -1,6 +1,7 @@
pub mod driver;
pub mod cpu;
pub mod interrupt;
pub mod paging;
pub fn init() {
cpu::enable_nxe_bit();

@ -1,5 +1,4 @@
use super::{Page, ENTRY_COUNT};
use super::entry::*;
use super::table::{self, Table, Level4, Level1};
use memory::*;
use core::ptr::Unique;
@ -26,7 +25,7 @@ impl Mapper {
pub fn translate(&self, virtual_address: VirtualAddress) -> Option<PhysicalAddress> {
let offset = virtual_address % PAGE_SIZE;
self.translate_page(Page::containing_address(virtual_address))
.map(|frame| PhysicalAddress((frame.number * PAGE_SIZE + offset) as u64))
.map(|frame| PhysicalAddress((frame.start_address().get() + offset) as u64))
}
pub fn translate_page(&self, page: Page) -> Option<Frame> {
@ -39,11 +38,11 @@ impl Mapper {
if let Some(start_frame) = p3_entry.pointed_frame() {
if p3_entry.flags().contains(HUGE_PAGE) {
// address must be 1GiB aligned
assert!(start_frame.number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
return Some(Frame {
number: start_frame.number + page.p2_index() *
ENTRY_COUNT + page.p1_index(),
});
assert!(start_frame.start_address().get() % (ENTRY_COUNT * ENTRY_COUNT * PAGE_SIZE) == 0);
return Some(Frame::containing_address(
start_frame.start_address().get() +
(page.p2_index() * ENTRY_COUNT + page.p1_index()) * PAGE_SIZE
));
}
}
if let Some(p2) = p3.next_table(page.p3_index()) {
@ -52,10 +51,10 @@ impl Mapper {
if let Some(start_frame) = p2_entry.pointed_frame() {
if p2_entry.flags().contains(HUGE_PAGE) {
// address must be 2MiB aligned
assert!(start_frame.number % ENTRY_COUNT == 0);
return Some(Frame {
number: start_frame.number + page.p1_index()
});
assert!(start_frame.start_address().get() % ENTRY_COUNT == 0);
return Some(Frame::containing_address(
start_frame.start_address().get() + page.p1_index() * PAGE_SIZE
));
}
}
}

@ -1,7 +1,7 @@
pub use self::entry::*;
pub use self::mapper::Mapper;
use core::ops::{Deref, DerefMut, Add};
use super::*;
use memory::*;
pub use self::temporary_page::TemporaryPage;
mod entry;
@ -151,7 +151,9 @@ impl ActivePageTable {
}
pub struct InactivePageTable {
pub(in memory) p4_frame: Frame,
// WARNING: Don't change the struct.
// memory mod use the private p4_frame.
p4_frame: Frame,
}
impl InactivePageTable {

@ -1,8 +1,8 @@
use core::marker::PhantomData;
use core::ops::{Index, IndexMut};
use memory::FrameAllocator;
use memory::paging::entry::*;
use memory::paging::ENTRY_COUNT;
use super::entry::*;
use super::ENTRY_COUNT;
pub const P4: *mut Table<Level4> = 0xffffffff_fffff000 as *mut _;

@ -86,8 +86,8 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) {
} else {
arch::driver::pic::init();
}
arch::interrupt::enable();
loop{}
unsafe{ arch::interrupt::enable(); }
test_end!();
}

@ -3,12 +3,16 @@ pub use x86_64::{PhysicalAddress};
pub type VirtualAddress = usize;
pub trait FromToVirtualAddress {
fn get(&self) -> usize;
fn to_identity_virtual(&self) -> VirtualAddress;
fn to_kernel_virtual(&self) -> VirtualAddress;
fn from_kernel_virtual(addr: VirtualAddress) -> Self;
}
impl FromToVirtualAddress for PhysicalAddress {
fn get(&self) -> usize {
self.0 as usize
}
fn to_identity_virtual(&self) -> VirtualAddress {
self.0 as usize
}

@ -0,0 +1,53 @@
use super::address::PhysicalAddress;
pub const PAGE_SIZE: usize = 4096;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Frame {
pub(super) number: usize,
}
impl Frame {
pub fn containing_address(address: usize) -> Frame {
Frame{ number: address / PAGE_SIZE }
}
//TODO: Set private
pub fn start_address(&self) -> PhysicalAddress {
PhysicalAddress((self.number * PAGE_SIZE) as u64)
}
pub fn clone(&self) -> Frame {
Frame { number: self.number }
}
//TODO: Set private
pub fn range_inclusive(start: Frame, end: Frame) -> FrameIter {
FrameIter {
start: start,
end: end,
}
}
}
pub struct FrameIter {
start: Frame,
end: Frame,
}
impl Iterator for FrameIter {
type Item = Frame;
fn next(&mut self) -> Option<Frame> {
if self.start <= self.end {
let frame = self.start.clone();
self.start.number += 1;
Some(frame)
} else {
None
}
}
}
pub trait FrameAllocator {
fn allocate_frame(&mut self) -> Option<Frame>;
fn deallocate_frame(&mut self, frame: Frame);
}

@ -1,18 +1,18 @@
pub use self::area_frame_allocator::AreaFrameAllocator;
pub use self::paging::*;
pub use arch::paging::*;
pub use self::stack_allocator::Stack;
pub use self::address::*;
pub use self::frame::*;
use multiboot2::BootInformation;
use consts::KERNEL_OFFSET;
use arch::paging;
mod area_frame_allocator;
pub mod heap_allocator;
mod paging;
mod stack_allocator;
mod address;
pub const PAGE_SIZE: usize = 4096;
mod frame;
pub fn init(boot_info: &BootInformation) -> MemoryController {
assert_has_not_been_called!("memory::init must be called only once");
@ -133,8 +133,11 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
println!("NEW TABLE!!!");
// turn the old p4 page into a guard page
let old_table_p4_frame = unsafe {
&*(&old_table as *const InactivePageTable as *const Frame)
};
let old_p4_page = Page::containing_address(
old_table.p4_frame.start_address().to_kernel_virtual()
old_table_p4_frame.start_address().to_kernel_virtual()
);
active_table.unmap(old_p4_page, allocator);
println!("guard page at {:#x}", old_p4_page.start_address());
@ -142,56 +145,6 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
active_table
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Frame {
number: usize,
}
impl Frame {
fn containing_address(address: usize) -> Frame {
Frame{ number: address / PAGE_SIZE }
}
fn start_address(&self) -> PhysicalAddress {
PhysicalAddress((self.number * PAGE_SIZE) as u64)
}
fn clone(&self) -> Frame {
Frame { number: self.number }
}
fn range_inclusive(start: Frame, end: Frame) -> FrameIter {
FrameIter {
start: start,
end: end,
}
}
}
struct FrameIter {
start: Frame,
end: Frame,
}
impl Iterator for FrameIter {
type Item = Frame;
fn next(&mut self) -> Option<Frame> {
if self.start <= self.end {
let frame = self.start.clone();
self.start.number += 1;
Some(frame)
} else {
None
}
}
}
pub trait FrameAllocator {
fn allocate_frame(&mut self) -> Option<Frame>;
fn deallocate_frame(&mut self, frame: Frame);
}
pub struct MemoryController {
active_table: paging::ActivePageTable,
frame_allocator: AreaFrameAllocator,

Loading…
Cancel
Save