From 28300182f2968467f1cfa98c7574ec89718bdf78 Mon Sep 17 00:00:00 2001 From: Amelia Coutard Date: Tue, 11 Oct 2022 08:38:45 +0200 Subject: [PATCH] Moved the GDT to the higher half (added a second lgdt after jump to 64 bits), to allow for unmapping the whole lower half --- src/boot.S | 12 +++++++++++- src/kernel.cpp | 6 ++++-- src/paging.cpp | 8 ++++---- src/paging.hpp | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/boot.S b/src/boot.S index 9faf67a..d265748 100644 --- a/src/boot.S +++ b/src/boot.S @@ -188,11 +188,21 @@ _start: mov %eax, %cr0 # Jump to 64 bits: - lgdt (GDT.PTR - KERNEL_VMA) + lgdt GDT.PTR - KERNEL_VMA jmp $GDT.KERNEL_CODE, $.trampoline .code64 .trampoline: + mov %esp, %esp + + movq $GDT, GDT.PTR + 2 + lgdt GDT.PTR # Reload GDT in higher half. + pushq $GDT.KERNEL_CODE + movabsq $.trampoline2, %rax + pushq %rax + lretq # Jump to new GDT. +.trampoline2: + mov $GDT.KERNEL_DATA, %ax # Set the A-register to the data descriptor. mov %ax, %ds # Set the data segment to the A-register. mov %ax, %es # Set the extra segment to the A-register. diff --git a/src/kernel.cpp b/src/kernel.cpp index a52ecab..baf2dc7 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -5,6 +5,7 @@ #include "interrupts.hpp" os::idt<32> idt; +extern "C" os::paging::PML4T PML4T; extern "C" void kmain(unsigned long magic, os::phys_ptr info) { os::assert(magic == 0x36D76289, "Incorrect magic number: wasn't booted with multiboot2."); @@ -129,8 +130,9 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr PML4T = nullptr; - asm ("movq $PML4T - 0xFFFFFFFF80000000,%0" : "=ri"(PML4T) : ); + PML4T.contents[0].base_address()->contents[0].P(false); + PML4T.contents[0].base_address()->contents[1].P(false); + PML4T.contents[0].P(false); os::print("Mapping:\n"); os::paging::print_mapping(PML4T); diff --git a/src/paging.cpp b/src/paging.cpp index 9c2f133..7d0f9ff 100644 --- a/src/paging.cpp +++ b/src/paging.cpp @@ -3,9 +3,9 @@ // 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, bool show_higher_half) { +template void print_mapping(const os::paging::paging_table& table, std::uint64_t virt_address, bool show_higher_half) { for (std::size_t i = 0; i < (order == 3 && !show_higher_half ? 256 : 512); i++) { - const auto& page = table->contents[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); @@ -18,12 +18,12 @@ template void print_mapping(os::phys_ptr 0) { // Will never be false when !page.is_page(). - print_mapping(page.base_address(), new_virt, show_higher_half); + print_mapping(*page.base_address(), new_virt, show_higher_half); } } } } -void os::paging::print_mapping(phys_ptr PML4T, bool show_higher_half) { +void os::paging::print_mapping(const PML4T& PML4T, bool show_higher_half) { ::print_mapping(PML4T, 0, show_higher_half); } diff --git a/src/paging.hpp b/src/paging.hpp index 83a556f..347733b 100644 --- a/src/paging.hpp +++ b/src/paging.hpp @@ -152,7 +152,7 @@ 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, bool show_higher_half = false); +void print_mapping(const PML4T& PML4T, bool show_higher_half = false); class page_allocator_t; extern page_allocator_t page_allocator; -- 2.47.0