diff --git a/src/arch/aarch64/mm/mod.rs b/src/arch/aarch64/mm/mod.rs index e797888e27..b7460ec27e 100644 --- a/src/arch/aarch64/mm/mod.rs +++ b/src/arch/aarch64/mm/mod.rs @@ -1,15 +1 @@ pub mod paging; - -use crate::mm::{FrameAlloc, PageAlloc, PageRangeAllocator}; - -pub unsafe fn init() { - unsafe { - paging::init(); - } - unsafe { - FrameAlloc::init(); - } - unsafe { - PageAlloc::init(); - } -} diff --git a/src/arch/mod.rs b/src/arch/mod.rs index 7a672be4e4..02e742a58f 100644 --- a/src/arch/mod.rs +++ b/src/arch/mod.rs @@ -48,7 +48,7 @@ cfg_if::cfg_if! { }; pub use self::x86_64::mm::paging::{BasePageSize, PageSize}; #[cfg(feature = "common-os")] - pub use self::x86_64::mm::create_new_root_page_table; + pub use self::x86_64::mm::paging::create_new_root_page_table; #[cfg(feature = "common-os")] pub use self::x86_64::kernel::{load_application, jump_to_user_land}; } else if #[cfg(target_arch = "riscv64")] { diff --git a/src/arch/riscv64/mm/mod.rs b/src/arch/riscv64/mm/mod.rs index d55d4f6667..b7460ec27e 100644 --- a/src/arch/riscv64/mm/mod.rs +++ b/src/arch/riscv64/mm/mod.rs @@ -1,15 +1 @@ pub mod paging; - -use crate::mm::{FrameAlloc, PageAlloc, PageRangeAllocator}; - -pub unsafe fn init() { - unsafe { - FrameAlloc::init(); - } - unsafe { - PageAlloc::init(); - } - unsafe { - self::paging::enable_page_table(); - } -} diff --git a/src/arch/x86_64/mm/mod.rs b/src/arch/x86_64/mm/mod.rs index f8bd316587..de4a78a7f8 100644 --- a/src/arch/x86_64/mm/mod.rs +++ b/src/arch/x86_64/mm/mod.rs @@ -1,79 +1 @@ pub(crate) mod paging; - -use memory_addresses::arch::x86_64::{PhysAddr, VirtAddr}; -#[cfg(feature = "common-os")] -use x86_64::structures::paging::{PageSize, Size4KiB as BasePageSize}; - -#[cfg(feature = "common-os")] -use crate::arch::mm::paging::{PageTableEntryFlags, PageTableEntryFlagsExt}; -use crate::mm::{FrameAlloc, PageAlloc, PageRangeAllocator}; - -#[cfg(feature = "common-os")] -pub fn create_new_root_page_table() -> usize { - use free_list::PageLayout; - use x86_64::registers::control::Cr3; - - use crate::mm::{FrameAlloc, PageBox, PageRangeAllocator}; - - let layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap(); - let frame_range = FrameAlloc::allocate(layout).unwrap(); - let physaddr = PhysAddr::from(frame_range.start()); - - let layout = PageLayout::from_size(2 * BasePageSize::SIZE as usize).unwrap(); - let page_range = PageBox::new(layout).unwrap(); - let virtaddr = VirtAddr::from(page_range.start()); - let mut flags = PageTableEntryFlags::empty(); - flags.normal().writable(); - - let entry: u64 = unsafe { - let (frame, _flags) = Cr3::read(); - paging::map::(virtaddr, frame.start_address().into(), 1, flags); - let entry: &u64 = &*virtaddr.as_ptr(); - - *entry - }; - - let slice_addr = virtaddr + BasePageSize::SIZE; - paging::map::(slice_addr, physaddr, 1, flags); - - unsafe { - let pml4 = core::slice::from_raw_parts_mut(slice_addr.as_mut_ptr(), 512); - - // clear PML4 - for elem in pml4.iter_mut() { - *elem = 0; - } - - // copy first element and the self reference - pml4[0] = entry; - // create self reference - pml4[511] = physaddr.as_u64() + 0x3; // PG_PRESENT | PG_RW - }; - - paging::unmap::(virtaddr, 2); - - physaddr.as_usize() -} - -pub unsafe fn init() { - paging::init(); - unsafe { - FrameAlloc::init(); - } - unsafe { - paging::log_page_tables(); - } - unsafe { - PageAlloc::init(); - } - - #[cfg(feature = "common-os")] - { - use x86_64::registers::control::Cr3; - - let (frame, _flags) = Cr3::read(); - crate::scheduler::BOOT_ROOT_PAGE_TABLE - .set(frame.start_address().as_u64().try_into().unwrap()) - .unwrap(); - } -} diff --git a/src/arch/x86_64/mm/paging.rs b/src/arch/x86_64/mm/paging.rs index 96d1e50469..6916754b9d 100644 --- a/src/arch/x86_64/mm/paging.rs +++ b/src/arch/x86_64/mm/paging.rs @@ -2,6 +2,7 @@ use core::fmt::Debug; use core::ptr; use free_list::PageLayout; +use memory_addresses::arch::x86_64::{PhysAddr, VirtAddr}; use x86_64::registers::control::{Cr0, Cr0Flags, Cr2, Cr3}; #[cfg(feature = "common-os")] use x86_64::registers::segmentation::SegmentSelector; @@ -16,7 +17,6 @@ use x86_64::structures::paging::{ }; use crate::arch::x86_64::kernel::processor; -use crate::arch::x86_64::mm::{PhysAddr, VirtAddr}; use crate::mm::{FrameAlloc, PageRangeAllocator}; use crate::{env, scheduler}; @@ -309,11 +309,21 @@ pub(crate) extern "x86-interrupt" fn page_fault_handler( scheduler::abort(); } -pub fn init() { +pub unsafe fn init() { unsafe { log_page_tables(); } make_p4_writable(); + + #[cfg(feature = "common-os")] + { + use x86_64::registers::control::Cr3; + + let (frame, _flags) = Cr3::read(); + crate::scheduler::BOOT_ROOT_PAGE_TABLE + .set(frame.start_address().as_u64().try_into().unwrap()) + .unwrap(); + } } fn make_p4_writable() { @@ -362,6 +372,54 @@ fn make_p4_writable() { unsafe { without_protect(make_writable) } } +#[cfg(feature = "common-os")] +pub fn create_new_root_page_table() -> usize { + use free_list::PageLayout; + use x86_64::registers::control::Cr3; + use x86_64::structures::paging::{PageSize, Size4KiB as BasePageSize}; + + use crate::mm::{FrameAlloc, PageBox, PageRangeAllocator}; + + let layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap(); + let frame_range = FrameAlloc::allocate(layout).unwrap(); + let physaddr = PhysAddr::from(frame_range.start()); + + let layout = PageLayout::from_size(2 * BasePageSize::SIZE as usize).unwrap(); + let page_range = PageBox::new(layout).unwrap(); + let virtaddr = VirtAddr::from(page_range.start()); + let mut flags = PageTableEntryFlags::empty(); + flags.normal().writable(); + + let entry: u64 = unsafe { + let (frame, _flags) = Cr3::read(); + map::(virtaddr, frame.start_address().into(), 1, flags); + let entry: &u64 = &*virtaddr.as_ptr(); + + *entry + }; + + let slice_addr = virtaddr + BasePageSize::SIZE; + map::(slice_addr, physaddr, 1, flags); + + unsafe { + let pml4 = core::slice::from_raw_parts_mut(slice_addr.as_mut_ptr(), 512); + + // clear PML4 + for elem in pml4.iter_mut() { + *elem = 0; + } + + // copy first element and the self reference + pml4[0] = entry; + // create self reference + pml4[511] = physaddr.as_u64() + 0x3; // PG_PRESENT | PG_RW + }; + + unmap::(virtaddr, 2); + + physaddr.as_usize() +} + pub unsafe fn log_page_tables() { use log::Level; diff --git a/src/mm/mod.rs b/src/mm/mod.rs index c1af654508..6df431c2fd 100644 --- a/src/mm/mod.rs +++ b/src/mm/mod.rs @@ -93,7 +93,21 @@ pub(crate) fn init() { Lazy::force(&KERNEL_ADDR_RANGE); unsafe { - arch::mm::init(); + arch::mm::paging::init(); + } + unsafe { + FrameAlloc::init(); + } + #[cfg(target_arch = "x86_64")] + unsafe { + arch::mm::paging::log_page_tables(); + } + unsafe { + PageAlloc::init(); + } + #[cfg(target_arch = "riscv64")] + unsafe { + arch::mm::paging::enable_page_table(); } let total_mem = physicalmem::total_memory_size();