From 4c4f72b865facbe770e0f77c4f7f9c5664246ee5 Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 13 Nov 2022 15:33:53 +0100 Subject: [PATCH] More MMU stuff, but writing still fails --- kernel/src/arch/MMU.h | 6 +++--- kernel/src/arch/x86_64/MMU.cpp | 30 ++++++++++++++++++++---------- kernel/src/main.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/kernel/src/arch/MMU.h b/kernel/src/arch/MMU.h index 0d22e16f..5f6fac42 100644 --- a/kernel/src/arch/MMU.h +++ b/kernel/src/arch/MMU.h @@ -15,11 +15,11 @@ namespace MMU CacheDisable = 16, }; - Result map(u64 virt, u64 phys, Flags flags); + Result map(u64 virt, u64 phys, int flags); Result unmap(u64 virt); Result get_physical(u64 virt); - Result get_flags(u64 virt); - Result remap(u64 virt, Flags flags); + Result get_flags(u64 virt); + Result remap(u64 virt, int flags); void switch_page_directory(PageDirectory* dir); PageDirectory* get_page_directory(); diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index 2a04b554..1ccc1c08 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -1,5 +1,6 @@ #include "arch/MMU.h" #include "MemoryManager.h" +#include #define PAGE_SIZE 4096 @@ -148,7 +149,7 @@ namespace MMU asm volatile("invlpg (%0)" : : "r"(page) : "memory"); } - Flags arch_flags_to_mmu(PageTableEntry& entry) + int arch_flags_to_mmu(PageTableEntry& entry) { int result = Flags::None; if (entry.read_write) result |= Flags::ReadWrite; @@ -156,10 +157,10 @@ namespace MMU if (entry.no_execute) result |= Flags::NoExecute; if (entry.write_through) result |= Flags::WriteThrough; if (entry.cache_disabled) result |= Flags::CacheDisable; - return (Flags)result; + return result; } - Result map(u64 virt, u64 phys, Flags flags) + Result map(u64 virt, u64 phys, int flags) { auto& l4 = l4_entry(virt); if (!l4.present) @@ -167,34 +168,43 @@ namespace MMU auto addr = MemoryManager::alloc_physical_page(); if (addr.has_error()) return addr.release_error(); l4.present = true; - if (flags & Flags::ReadWrite) l4.read_write = true; - if (flags & Flags::User) l4.user = true; l4.set_address(addr.release_value()); + memset(l3_table(virt), 0, PAGE_SIZE); } + if (flags & Flags::ReadWrite) l4.read_write = true; + if (flags & Flags::User) l4.user = true; + auto& l3 = l3_entry(virt); if (!l3.present) { auto addr = MemoryManager::alloc_physical_page(); if (addr.has_error()) return addr.release_error(); l3.present = true; - if (flags & Flags::ReadWrite) l3.read_write = true; - if (flags & Flags::User) l3.user = true; l3.set_address(addr.release_value()); + memset(l2_table(virt), 0, PAGE_SIZE); } + if (flags & Flags::ReadWrite) l3.read_write = true; + if (flags & Flags::User) l3.user = true; + if (l3.larger_pages) return err; // FIXME: Replacing larger pages is not supported ATM + auto& l2 = l2_entry(virt); if (!l2.present) { auto addr = MemoryManager::alloc_physical_page(); if (addr.has_error()) return addr.release_error(); l2.present = true; - if (flags & Flags::ReadWrite) l2.read_write = true; - if (flags & Flags::User) l2.user = true; l2.set_address(addr.release_value()); + memset(l1_table(virt), 0, PAGE_SIZE); } + if (flags & Flags::ReadWrite) l2.read_write = true; + if (flags & Flags::User) l2.user = true; + if (l2.larger_pages) return err; // FIXME: Replacing larger pages is not supported ATM + auto& l1 = l1_entry(virt); bool was_present = l1.present; + l1.present = true; if (flags & Flags::ReadWrite) l1.read_write = true; if (flags & Flags::User) l1.user = true; if (flags & Flags::WriteThrough) l1.write_through = true; @@ -220,7 +230,7 @@ namespace MMU return l1.get_address(); } - Result get_flags(u64 virt) + Result get_flags(u64 virt) { auto& l4 = l4_entry(virt); if (!l4.present) return err; diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 75d83cae..2731e861 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,5 +1,6 @@ #include "Framebuffer.h" #include "Init.h" +#include "MemoryManager.h" #include "arch/MMU.h" #include "arch/Serial.h" @@ -16,6 +17,34 @@ extern "C" void _start() Serial::println(MMU::get_physical((u64)fb).has_error() ? "fb is not mapped" : "fb is mapped!!"); + const u64 address = 0xfffffffff8000000; + + u64 physical = MemoryManager::alloc_physical_page().release_value(); + + bool success = !MMU::map(address, physical, MMU::ReadWrite | MMU::NoExecute).has_error(); + + if (success) Serial::println("Mapped page :)"); + else + Serial::println("Failed to map page"); + + if (MMU::get_physical(address).release_value() == physical) Serial::println("Mapping is active ;)"); + else + Serial::println("Mapping is not active"); + + int flags = MMU::get_flags(address).release_value(); + + if (flags & MMU::ReadWrite) Serial::println("Mapping is writable"); + if (flags & MMU::NoExecute) Serial::println("Mapping is not executable"); + + u32* ptr = (u32*)address; + (void)*ptr; + + Serial::println("Can read from pointer"); + + *ptr = 8; + + Serial::println("Can write to pointer"); + for (;;) ; } \ No newline at end of file