hermit/arch/x86_64/mm/
mod.rs1pub(crate) mod paging;
2pub(crate) mod physicalmem;
3pub(crate) mod virtualmem;
4
5use memory_addresses::arch::x86_64::{PhysAddr, VirtAddr};
6#[cfg(feature = "common-os")]
7use x86_64::structures::paging::{PageSize, Size4KiB as BasePageSize};
8
9pub use self::paging::init_page_tables;
10#[cfg(feature = "common-os")]
11use crate::arch::mm::paging::{PageTableEntryFlags, PageTableEntryFlagsExt};
12
13#[cfg(feature = "common-os")]
14pub fn create_new_root_page_table() -> usize {
15 use x86_64::registers::control::Cr3;
16
17 let physaddr =
18 physicalmem::allocate_aligned(BasePageSize::SIZE as usize, BasePageSize::SIZE as usize)
19 .unwrap();
20 let virtaddr =
21 virtualmem::allocate_aligned(2 * BasePageSize::SIZE as usize, BasePageSize::SIZE as usize)
22 .unwrap();
23 let mut flags = PageTableEntryFlags::empty();
24 flags.normal().writable();
25
26 let entry: u64 = unsafe {
27 let (frame, _flags) = Cr3::read();
28 paging::map::<BasePageSize>(virtaddr, frame.start_address().into(), 1, flags);
29 let entry: &u64 = &*virtaddr.as_ptr();
30
31 *entry
32 };
33
34 let slice_addr = virtaddr + BasePageSize::SIZE;
35 paging::map::<BasePageSize>(slice_addr, physaddr, 1, flags);
36
37 unsafe {
38 let pml4 = core::slice::from_raw_parts_mut(slice_addr.as_mut_ptr(), 512);
39
40 for elem in pml4.iter_mut() {
42 *elem = 0;
43 }
44
45 pml4[0] = entry;
47 pml4[511] = physaddr.as_u64() + 0x3; };
50
51 paging::unmap::<BasePageSize>(virtaddr, 2);
52 virtualmem::deallocate(virtaddr, 2 * BasePageSize::SIZE as usize);
53
54 physaddr.as_usize()
55}
56
57pub fn init() {
58 paging::init();
59 physicalmem::init();
60 virtualmem::init();
61
62 #[cfg(feature = "common-os")]
63 {
64 use x86_64::registers::control::Cr3;
65
66 let (frame, _flags) = Cr3::read();
67 crate::scheduler::BOOT_ROOT_PAGE_TABLE
68 .set(frame.start_address().as_u64().try_into().unwrap())
69 .unwrap();
70 }
71}