From 1e725dc33d7993bf16952320467d9d36f7b9b65b Mon Sep 17 00:00:00 2001 From: Amelia Coutard Date: Sun, 12 Jun 2022 04:08:31 +0200 Subject: [PATCH] Added a way to print the entire virtual memory map. Also added missing consts in paging_entry --- src/boot.S | 1 + src/kernel.cpp | 4 ++++ src/paging.cpp | 27 +++++++++++++++++++++++++++ src/paging.hpp | 36 ++++++++++++++++++++---------------- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/boot.S b/src/boot.S index 955503c..ef9fce4 100644 --- a/src/boot.S +++ b/src/boot.S @@ -90,6 +90,7 @@ IO_MAP: IO_MAP_END: .align 0x1000 +.globl PML4T PML4T: .quad PDPT_low - KERNEL_VMA + 3 .skip 0x1000 - 16 .quad PDPT_high - KERNEL_VMA + 3 diff --git a/src/kernel.cpp b/src/kernel.cpp index 1cfa10e..3994028 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -152,6 +152,10 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr PML4T = nullptr; + asm ("movq $PML4T - 0xFFFFFFFF80000000,%0" : "=ri"(PML4T) : ); + os::paging::print_mapping(PML4T); + while (true) { os::hlt(); } diff --git a/src/paging.cpp b/src/paging.cpp index a09639c..107ac85 100644 --- a/src/paging.cpp +++ b/src/paging.cpp @@ -1,4 +1,31 @@ #include "paging.hpp" +#include "serial.hpp" + +// void os::paging::unmap(phys_ptr PLM4T, page* virt, std::uint64_t length) { } +// void os::paging::map(phys_ptr PLM4T, page* virt, std::uint64_t length, phys_ptr phys) { } +template void print_mapping(os::phys_ptr> table, std::uint64_t virt_address) { + for (std::size_t i = 0; i < 512; i++) { + const auto& page = table->contents[i]; + if (!page.P()) { continue; } + std::uint64_t new_virt = virt_address + i * (4096ul << (order * 9)); + new_virt |= ((new_virt & 0x0000800000000000) != 0 ? 0xFFFF000000000000 : 0); + if (page.is_page()) { + os::print(new_virt); + os::print(" -> "); + os::print(page.base_address().get_phys_addr()); + os::print(" (order "); + os::printc(order + '0'); + os::print(")\n"); + } else { + if constexpr (order > 0) { // Will never be false when !page.is_page(). + print_mapping(page.base_address(), new_virt); + } + } + } +} +void os::paging::print_mapping(phys_ptr PML4T) { + ::print_mapping(PML4T, 0); +} os::paging::page one_past_end_page_for_page_allocator; os::paging::page_allocator_t os::paging::page_allocator(os::phys_ptr(reinterpret_cast(&one_past_end_page_for_page_allocator) - 0xFFFFFFFF80000000)); diff --git a/src/paging.hpp b/src/paging.hpp index 9bc9f25..86cdf4d 100644 --- a/src/paging.hpp +++ b/src/paging.hpp @@ -20,17 +20,17 @@ public: data |= 1 << 7; // Mark as smallest page. } } - inline bool is_page() { + inline bool is_page() const { return order == 0 || (data & (1 << 7)) != 0; } - inline bool NX() { + inline bool NX() const { return (data & (1ul << 63)) != 0; } inline void NX(bool v) { data = (data & ~(1ul << 63)) | (v ? (1ul << 63) : 0); } - inline unsigned PK() { + inline unsigned PK() const { os::assert(is_page(), "read protection key of non-page."); return (data >> 52) & 0xF; } @@ -39,29 +39,29 @@ public: os::assert((v & 0xF) == v, "incorrect protection key."); data = (data & ~(0xFul << 59)) | (std::uint64_t(v) << 59); } - inline unsigned AVL_high() { + inline unsigned AVL_high() const { return (data >> 52) & (is_page() ? 0x7F : 0x7FF); } inline void AVL_high(unsigned v) { os::assert((v & (is_page() ? 0x7F : 0x7FF)) == v, "incorrect AVL high bits."); data = (data & ~((is_page() ? 0x7Ful : 0x7FFul) << 52)) | (std::uint64_t(v) << 52); } - inline phys_ptr> base_address() { - return {data & 0x000FFFFFFFFFF000 & ~(order != 0 && is_page() ? 1ul << 12 : 0ul)}; + inline phys_ptr> base_address() const { + return phys_ptr>{data & 0x000FFFFFFFFFF000 & ~(order != 0 && is_page() ? 1ul << 12 : 0ul)}; } inline void base_address(phys_ptr> v) { const std::uint64_t v_int = v.get_phys_addr(); os::assert((v_int & 0x000FFFFFFFFFF000 & (0xFFFFFFFFFFFFF000 << (is_page() ? 9 * order : 0))) == v_int, "incorrect base address."); data = (data & ~0x000FFFFFFFFFF000ul & ~(order != 0 && is_page() ? 1ul << 12 : 0ul)) | v_int; } - inline unsigned AVL_low() { + inline unsigned AVL_low() const { return (data >> 9) & 0x7; } inline void AVL_low(unsigned v) { os::assert((v & 0x7) == v, "incorrect AVL low bits"); data = (data & ~(0x7ul << 9)) | (v << 9); } - inline bool G() { + inline bool G() const { os::assert(is_page(), "read global bit of non-page."); return (data & (1 << 8)) != 0; } @@ -69,7 +69,7 @@ public: os::assert(is_page(), "write to global bit of non-page."); data = (data & ~(1ul << 8)) | (v ? 1 << 8 : 0); } - inline bool PAT() { + inline bool PAT() const { os::assert(is_page(), "read PAT bit of non-page."); return (data & (1 << (order == 0 ? 7 : 12))) != 0; } @@ -77,7 +77,7 @@ public: os::assert(is_page(), "write to PAT bit of non-page."); data = (data & ~(1ul << (order == 0 ? 7 : 12))) | (v ? 1 << (order == 0 ? 7 : 12) : 0); } - inline bool D() { + inline bool D() const { os::assert(is_page(), "read dirty bit of non-page."); return (data & (1 << 6)) != 0; } @@ -85,37 +85,37 @@ public: os::assert(is_page(), "write to dirty bit of non-page."); data = (data & ~(1ul << 6)) | (v ? 1 << 6 : 0); } - inline bool A() { + inline bool A() const { return (data & (1 << 5)) != 0; } inline void A(bool v) { data = (data & ~(1ul << 5)) | (v ? 1 << 5 : 0); } - inline bool PCD() { + inline bool PCD() const { return (data & (1 << 4)) != 0; } inline void PCD(bool v) { data = (data & ~(1ul << 4)) | (v ? 1 << 4 : 0); } - inline bool PWT() { + inline bool PWT() const { return (data & (1 << 3)) != 0; } inline void PWT(bool v) { data = (data & ~(1ul << 3)) | (v ? 1 << 3 : 0); } - inline bool U_S() { + inline bool U_S() const { return (data & (1 << 2)) != 0; } inline void U_S(bool v) { data = (data & ~(1ul << 2)) | (v ? 1 << 2 : 0); } - inline bool R_W() { + inline bool R_W() const { return (data & (1 << 1)) != 0; } inline void R_W(bool v) { data = (data & ~(1ul << 1)) | (v ? 1 << 1 : 0); } - inline bool P() { + inline bool P() const { return (data & (1 << 0)) != 0; } inline void P(bool v) { @@ -150,6 +150,10 @@ using PT = paging_table<0>; using PE = paging_entry<0>; using page = paging_table<-1>; +void unmap(phys_ptr PLM4T, page* virt, std::uint64_t length); +void map(phys_ptr PLM4T, page* virt, std::uint64_t length, phys_ptr phys); +void print_mapping(phys_ptr PML4T); + class page_allocator_t; extern page_allocator_t page_allocator; -- 2.47.0