From 77703442e72b6c60ce83b3df38396c8bc785321b Mon Sep 17 00:00:00 2001 From: WangRunji Date: Mon, 16 Apr 2018 01:04:23 +0800 Subject: [PATCH] Move `paging` mod to `arch`, as Redox did. --- src/arch/x86_64/interrupt.rs | 9 --- src/arch/x86_64/interrupt/mod.rs | 11 ++++ src/arch/x86_64/mod.rs | 1 + src/{memory => arch/x86_64}/paging/entry.rs | 0 src/{memory => arch/x86_64}/paging/mapper.rs | 21 +++---- src/{memory => arch/x86_64}/paging/mod.rs | 6 +- src/{memory => arch/x86_64}/paging/table.rs | 4 +- .../x86_64}/paging/temporary_page.rs | 0 src/lib.rs | 4 +- src/memory/address.rs | 4 ++ src/memory/frame.rs | 53 ++++++++++++++++ src/memory/mod.rs | 63 +++---------------- 12 files changed, 95 insertions(+), 81 deletions(-) delete mode 100644 src/arch/x86_64/interrupt.rs create mode 100644 src/arch/x86_64/interrupt/mod.rs rename src/{memory => arch/x86_64}/paging/entry.rs (100%) rename src/{memory => arch/x86_64}/paging/mapper.rs (84%) rename src/{memory => arch/x86_64}/paging/mod.rs (97%) rename src/{memory => arch/x86_64}/paging/table.rs (98%) rename src/{memory => arch/x86_64}/paging/temporary_page.rs (100%) create mode 100644 src/memory/frame.rs diff --git a/src/arch/x86_64/interrupt.rs b/src/arch/x86_64/interrupt.rs deleted file mode 100644 index 3b1e404..0000000 --- a/src/arch/x86_64/interrupt.rs +++ /dev/null @@ -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(); } -} \ No newline at end of file diff --git a/src/arch/x86_64/interrupt/mod.rs b/src/arch/x86_64/interrupt/mod.rs new file mode 100644 index 0000000..136c296 --- /dev/null +++ b/src/arch/x86_64/interrupt/mod.rs @@ -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(); +} \ No newline at end of file diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index 5e97be4..6bad638 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -1,6 +1,7 @@ pub mod driver; pub mod cpu; pub mod interrupt; +pub mod paging; pub fn init() { cpu::enable_nxe_bit(); diff --git a/src/memory/paging/entry.rs b/src/arch/x86_64/paging/entry.rs similarity index 100% rename from src/memory/paging/entry.rs rename to src/arch/x86_64/paging/entry.rs diff --git a/src/memory/paging/mapper.rs b/src/arch/x86_64/paging/mapper.rs similarity index 84% rename from src/memory/paging/mapper.rs rename to src/arch/x86_64/paging/mapper.rs index 5117fb5..f8f0df6 100644 --- a/src/memory/paging/mapper.rs +++ b/src/arch/x86_64/paging/mapper.rs @@ -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 { 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 { @@ -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 + )); } } } diff --git a/src/memory/paging/mod.rs b/src/arch/x86_64/paging/mod.rs similarity index 97% rename from src/memory/paging/mod.rs rename to src/arch/x86_64/paging/mod.rs index 1cb45cf..6d75cdb 100644 --- a/src/memory/paging/mod.rs +++ b/src/arch/x86_64/paging/mod.rs @@ -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 { diff --git a/src/memory/paging/table.rs b/src/arch/x86_64/paging/table.rs similarity index 98% rename from src/memory/paging/table.rs rename to src/arch/x86_64/paging/table.rs index 11003ce..bd50282 100644 --- a/src/memory/paging/table.rs +++ b/src/arch/x86_64/paging/table.rs @@ -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 = 0xffffffff_fffff000 as *mut _; diff --git a/src/memory/paging/temporary_page.rs b/src/arch/x86_64/paging/temporary_page.rs similarity index 100% rename from src/memory/paging/temporary_page.rs rename to src/arch/x86_64/paging/temporary_page.rs diff --git a/src/lib.rs b/src/lib.rs index 7202fd8..dcbbb5a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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!(); } diff --git a/src/memory/address.rs b/src/memory/address.rs index e472fdd..153b189 100644 --- a/src/memory/address.rs +++ b/src/memory/address.rs @@ -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 } diff --git a/src/memory/frame.rs b/src/memory/frame.rs new file mode 100644 index 0000000..6b9be48 --- /dev/null +++ b/src/memory/frame.rs @@ -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 { + 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; + fn deallocate_frame(&mut self, frame: Frame); +} \ No newline at end of file diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 915219a..54073f1 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -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(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(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 { - 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; - fn deallocate_frame(&mut self, frame: Frame); -} - pub struct MemoryController { active_table: paging::ActivePageTable, frame_allocator: AreaFrameAllocator,