Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions src/arch/aarch64/mm/mod.rs
Original file line number Diff line number Diff line change
@@ -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();
}
}
2 changes: 1 addition & 1 deletion src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")] {
Expand Down
14 changes: 0 additions & 14 deletions src/arch/riscv64/mm/mod.rs
Original file line number Diff line number Diff line change
@@ -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::init_page_tables();
}
}
2 changes: 1 addition & 1 deletion src/arch/riscv64/mm/paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ pub fn identity_map<S: PageSize>(phys_addr: PhysAddr) {
.map_pages(range, PhysAddr::new(first_page.address().as_u64()), flags);
}

pub unsafe fn init_page_tables() {
pub unsafe fn init() {
// FIXME: This is not sound, since we are ignoring races with the hardware.
unsafe {
satp::write(Satp::from_bits(
Expand Down
78 changes: 0 additions & 78 deletions src/arch/x86_64/mm/mod.rs
Original file line number Diff line number Diff line change
@@ -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::<BasePageSize>(virtaddr, frame.start_address().into(), 1, flags);
let entry: &u64 = &*virtaddr.as_ptr();

*entry
};

let slice_addr = virtaddr + BasePageSize::SIZE;
paging::map::<BasePageSize>(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::<BasePageSize>(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();
}
}
62 changes: 60 additions & 2 deletions src/arch/x86_64/mm/paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -17,7 +18,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};

Expand Down Expand Up @@ -314,11 +314,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() {
Expand Down Expand Up @@ -367,6 +377,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::<BasePageSize>(virtaddr, frame.start_address().into(), 1, flags);
let entry: &u64 = &*virtaddr.as_ptr();

*entry
};

let slice_addr = virtaddr + BasePageSize::SIZE;
map::<BasePageSize>(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::<BasePageSize>(virtaddr, 2);

physaddr.as_usize()
}

pub unsafe fn log_page_tables() {
use log::Level;

Expand Down
12 changes: 11 additions & 1 deletion src/mm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,17 @@ 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();
}

let total_mem = physicalmem::total_memory_size();
Expand Down
Loading