diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 3473a1f4..7406c571 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -65,7 +65,6 @@ SET(KERNEL_SRCS device/MouseDevice.cpp interrupt/IRQHandler.cpp memory/PageDirectory.cpp - memory/PageTable.cpp tasking/Process.cpp tasking/Thread.cpp tasking/Lock.cpp @@ -170,7 +169,8 @@ SET(KERNEL_SRCS net/UDPSocket.cpp net/TCPSocket.cpp net/Router.cpp - api/strerror.c) + api/strerror.c + constructors.cpp) IF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") SET(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/kernel/arch/i386/kernel.ld) @@ -184,6 +184,10 @@ IF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") arch/i386/tasking.cpp arch/i386/gdt.cpp arch/i386/kstdio.cpp + arch/i386/startup.cpp + arch/i386/PageTable.cpp + arch/i386/PageDirectory.cpp + arch/i386/MemoryManager.cpp arch/i386/asm/startup.s arch/i386/asm/tasking.s @@ -211,6 +215,8 @@ ELSEIF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64") arch/aarch64/startup.cpp arch/aarch64/kstdio.cpp arch/aarch64/MMU.cpp + arch/aarch64/PageDirectory.cpp + arch/aarch64/MemoryManager.cpp arch/aarch64/asm/startup.S arch/aarch64/asm/exception.S @@ -219,6 +225,7 @@ ELSEIF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64") arch/aarch64/rpi/GPIO.cpp arch/aarch64/rpi/Mailbox.cpp arch/aarch64/rpi/Framebuffer.cpp + arch/aarch64/rpi/DeviceInfo.cpp arch/aarch64/device/Device.cpp) ENDIF() diff --git a/kernel/CommandLine.cpp b/kernel/CommandLine.cpp index 67d3718e..28dbb35c 100644 --- a/kernel/CommandLine.cpp +++ b/kernel/CommandLine.cpp @@ -17,7 +17,6 @@ Copyright (c) Byteduck 2016-2020. All rights reserved. */ -#include #include #include "CommandLine.h" #include "kernel/memory/MemoryManager.h" diff --git a/kernel/KernelMapper.cpp b/kernel/KernelMapper.cpp index f67965b9..1586b3d3 100644 --- a/kernel/KernelMapper.cpp +++ b/kernel/KernelMapper.cpp @@ -21,7 +21,6 @@ #include #include "KernelMapper.h" #include -#include #include #include diff --git a/kernel/api/stdarg.h b/kernel/api/stdarg.h index 26644d87..7abfccf7 100644 --- a/kernel/api/stdarg.h +++ b/kernel/api/stdarg.h @@ -7,19 +7,12 @@ __DECL_BEGIN -typedef char* va_list; +typedef __builtin_va_list va_list; -#define __va_argsiz(t) \ - (((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) +#define va_start(ap, pN) __builtin_va_start(ap, pN) +#define va_end(ap) __builtin_va_end(ap) -#define va_start(ap, pN) \ - ((ap) = ((va_list) __builtin_next_arg(pN))) - -#define va_end(ap) ((void)0) - -#define va_arg(ap, t) \ - (((ap) = (ap) + __va_argsiz(t)), \ - *((t*) (void*) ((ap) - __va_argsiz(t)))) +#define va_arg(ap, t) __builtin_va_arg(ap, t) __DECL_END \ No newline at end of file diff --git a/kernel/arch/aarch64/MMU.cpp b/kernel/arch/aarch64/MMU.cpp index cfc8da16..60a84da5 100644 --- a/kernel/arch/aarch64/MMU.cpp +++ b/kernel/arch/aarch64/MMU.cpp @@ -10,8 +10,7 @@ using namespace Aarch64; -#define descriptor_addr(addr) (((addr) >> 12) & 0xFFFFFFFFF) - +// TODO: We could unmap these once we're done with them. __attribute__((aligned(4096), section(".meminit"))) MMU::TableDescriptor __initial_pgd_storage[512]; __attribute__((aligned(4096), section(".meminit"))) MMU::TableDescriptor __initial_pud_storage[512]; __attribute__((aligned(4096), section(".meminit"))) MMU::PageDescriptor __initial_pmd_storage[512]; @@ -21,11 +20,6 @@ auto* initial_pgd = (MMU::TableDescriptor*) (((size_t) &__initial_pgd_storage[0] auto* initial_pud = (MMU::TableDescriptor*) (((size_t) &__initial_pud_storage[0]) - HIGHER_HALF); auto* initial_pmd = (MMU::PageDescriptor*) (((size_t) &__initial_pmd_storage[0]) - HIGHER_HALF); -constexpr size_t pte_size = PAGE_SIZE; -constexpr size_t pmd_size = pte_size * 512; -constexpr size_t pud_size = pmd_size * 512; -constexpr size_t pgd_size = pud_size * 512; - void MMU::mmu_init() { /** Setup MAIR_EL1 attributes **/ Regs::MAIR mair_el1 = {.sections = {0}}; @@ -70,7 +64,7 @@ void MMU::mmu_init() { pmd.read_write = PageDescriptor::pRW; pmd.shareability = PageDescriptor::OuterShareable; pmd.access = true; - pmd.address = descriptor_addr(section * pmd_size + kernel_start_phys); + pmd.address = descriptor_addr(section * pmd_size + (kernel_start_phys / pmd_size) * pmd_size); } // TCR value. Map ttbr0/1 as follows: @@ -91,33 +85,13 @@ void MMU::mmu_init() { "tlbi vmalle1 \n" "dsb ish \n" "isb \n" - "mrs x5, sctlr_el1 \n" - "orr x5, x5, #0x1 \n" - "msr sctlr_el1, x5 \n" - "br %[mmu_fin] \n" + "mrs x4, sctlr_el1 \n" + "orr x4, x4, #0x1 \n" + "msr sctlr_el1, x4 \n" :: [ttbr_val]"r"(initial_pgd), [tcr_val]"r"(tcr.value), - [mair_val]"r"(mair_el1.value), - [mmu_fin]"r"((uint64_t) &&mmu_fin | HIGHER_HALF) // TODO: Why do I have to OR with HIGHER_HALF to get those upper bits set..? - : "x5"); -mmu_fin: - // Correct our stack pointer and return address - asm volatile ( - "mov x0, #0 \n" - "msr ttbr0_el1, x0 \n" // Disable ttbr0 identity mapping - "tlbi vmalle1 \n" // Flush tlb - - "mov x0, sp \n" // OR high bits into sp - "mov x1, #" STR(HIGHER_HALF) "\n" - "orr x0, x0, x1 \n" - "mov sp, x0 \n" - - "mov x0, lr \n" // OR high bits into lr - "orr x0, x0, x1 \n" - "mov lr, x0 \n" - - "ret \n" // Manual ret or else the compiler will screw with it - ::: "x0", "x1"); + [mair_val]"r"(mair_el1.value) + : "x4"); } void MMU::mem_early_panic(const char* str) { diff --git a/kernel/arch/aarch64/MMU.h b/kernel/arch/aarch64/MMU.h index 6f6404d1..a39d0e61 100644 --- a/kernel/arch/aarch64/MMU.h +++ b/kernel/arch/aarch64/MMU.h @@ -82,6 +82,47 @@ namespace Aarch64::Regs { } namespace Aarch64::MMU { + constexpr size_t pte_size = 4096; + constexpr size_t pmd_size = pte_size * 512; + constexpr size_t pud_size = pmd_size * 512; + constexpr size_t pgd_size = pud_size * 512; + + constexpr uint64_t descriptor_addr(size_t addr) { + return ((addr) >> 12) & 0xFFFFFFFFF; + } + + constexpr uint64_t pte_index(size_t addr) { + return ((addr) >> 12) & 0x1FF; + } + + constexpr uint64_t pte_page_index(size_t page) { + return page & 0x1FF; + } + + constexpr uint64_t pmd_index(size_t addr) { + return ((addr) >> 21) & 0x1FF; + } + + constexpr uint64_t pmd_page_index(size_t page) { + return ((page) >> 9) & 0x1FF; + } + + constexpr uint64_t pud_index(size_t addr) { + return ((addr) >> 30) & 0x1FF; + } + + constexpr uint64_t pud_page_index(size_t page) { + return ((page) >> 18) & 0x1FF; + } + + constexpr uint64_t pgd_index(size_t addr) { + return ((addr) >> 39) & 0x1FF; + } + + constexpr uint64_t pgd_page_index(size_t page) { + return ((page) >> 27) & 0x1FF; + } + enum Attr: uint8_t { NormalUncacheable = 0, NormalCacheable = 1, diff --git a/kernel/arch/aarch64/MemoryManager.cpp b/kernel/arch/aarch64/MemoryManager.cpp new file mode 100644 index 00000000..c19680dd --- /dev/null +++ b/kernel/arch/aarch64/MemoryManager.cpp @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#include +#include "rpi/DeviceInfo.h" + +void MemoryManager::setup_device_memory_map() { + size_t kernel_start_page = (KERNEL_START - HIGHER_HALF) / PAGE_SIZE; + size_t kernel_end_page = (KERNEL_END - HIGHER_HALF + PAGE_SIZE - 1) / PAGE_SIZE; + size_t sdram_end_page = (RPi::DeviceInfo::inst().sdram_size() + RPi::DeviceInfo::inst().sdram_start()) / PAGE_SIZE; + m_physical_regions.push_back(new PhysicalRegion( + RPi::DeviceInfo::inst().sdram_start() / PAGE_SIZE, + kernel_start_page - (RPi::DeviceInfo::inst().sdram_start() / PAGE_SIZE), + false, false)); + m_physical_regions.push_back(new PhysicalRegion( + kernel_start_page, + kernel_end_page - kernel_start_page, + false, true)); + m_physical_regions.push_back(new PhysicalRegion( + kernel_end_page, + sdram_end_page - kernel_end_page, + false, false)); + m_physical_regions.push_back(new PhysicalRegion( + RPi::DeviceInfo::inst().mmio_start() / PAGE_SIZE, + RPi::DeviceInfo::inst().mmio_size() / PAGE_SIZE, + true, true)); + usable_bytes_ram = RPi::DeviceInfo::inst().sdram_size(); + total_bytes_ram = usable_bytes_ram; + mem_lower_limit = RPi::DeviceInfo::inst().sdram_start(); + mem_upper_limit = RPi::DeviceInfo::inst().mmio_start() + RPi::DeviceInfo::inst().mmio_size(); +} \ No newline at end of file diff --git a/kernel/arch/aarch64/PageDirectory.cpp b/kernel/arch/aarch64/PageDirectory.cpp new file mode 100644 index 00000000..31b38de9 --- /dev/null +++ b/kernel/arch/aarch64/PageDirectory.cpp @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#include "kernel/kstd/vector.hpp" +#include "kernel/tasking/TaskManager.h" +#include "kernel/kstd/defines.h" +#include "kernel/Atomic.h" +#include "kernel/memory/MemoryManager.h" +#include "kernel/kstd/KLog.h" +#include "kernel/KernelMapper.h" +#include "kernel/kstd/cstring.h" +#include + +using namespace Aarch64; + +__attribute__((aligned(4096))) MMU::TableDescriptor __kernel_pgd[512]; +__attribute__((aligned(4096))) uint8_t g_early_paging_bump[PAGE_SIZE * 16]; +uint8_t* early_paging_bump_ptr = g_early_paging_bump; + +template +T* early_paging_alloc() { + static_assert((sizeof(T) * n) % 4096 == 0, "Size must be multiple of 4096"); + if (early_paging_bump_ptr >= (g_early_paging_bump + sizeof(g_early_paging_bump))) + PANIC("EARLY_PAGING_NOMEM", "Ran out of memory in the bump allocator when setting up paging."); + auto* ret = early_paging_bump_ptr; + early_paging_bump_ptr += sizeof(T) * n; + return (T*) ret; +} + +void PageDirectory::init_paging() { + setup_kernel_map(); + asm volatile("msr ttbr1_el1, %0" :: "r"((size_t) __kernel_pgd & ~HIGHER_HALF)); +} + +PageDirectory::PageDirectory(PageDirectory::DirectoryType type): m_type(type) { + if (m_type == DirectoryType::USER) { + // TODO + } else { + m_global_table.entries = __kernel_pgd; + start_page = HIGHER_HALF / PAGE_SIZE; + } +} + +PageDirectory::~PageDirectory() { + +} + +size_t PageDirectory::get_physaddr(size_t virtaddr) { + return 0; +} + +size_t PageDirectory::get_physaddr(void *virtaddr) { + return 0; +} + +bool PageDirectory::is_mapped(size_t vaddr, bool write) { + return false; +} + +bool PageDirectory::is_mapped() { + return false; +} + +Result PageDirectory::map_page(PageIndex vpage, PageIndex ppage, VMProt prot) { + ASSERT(vpage >= start_page); + vpage -= start_page; + + auto pud = m_global_table.get_child(MMU::pgd_page_index(vpage)); + auto pmd = pud->get_child(MMU::pud_page_index(vpage)); + auto pte = pmd->get_child(MMU::pmd_page_index(vpage)); + auto& page = pte->entries[MMU::pte_page_index(vpage)]; + page = { + .valid = true, + .type = MMU::PageDescriptor::Table, + .attr_index = MMU::Attr::NormalUncacheable, // TODO + .security = MMU::PageDescriptor::Secure, + .read_write = MMU::PageDescriptor::pRW, // TODO + .shareability = Aarch64::MMU::PageDescriptor::OuterShareable, + .access = true, + .address = MMU::descriptor_addr(ppage * PAGE_SIZE) + }; + + return Result(SUCCESS); +} + +Result PageDirectory::unmap_page(PageIndex vpage) { + return Result(ENOMEM); +} + +uint64_t* PageDirectory::alloc_table() { + return early_paging_alloc(); +} \ No newline at end of file diff --git a/kernel/arch/aarch64/asm/exception.S b/kernel/arch/aarch64/asm/exception.S index a5560b2c..61f69259 100644 --- a/kernel/arch/aarch64/asm/exception.S +++ b/kernel/arch/aarch64/asm/exception.S @@ -26,6 +26,8 @@ el3_to_el1: msr elr_el3, x0 mov x0, sp msr sp_el1, x0 + ldr x0, =CPACR_FPEN + msr cpacr_el1, x0 eret el2_to_el1: diff --git a/kernel/arch/aarch64/asm/exception.h b/kernel/arch/aarch64/asm/exception.h index 9e8ca58b..7869d269 100644 --- a/kernel/arch/aarch64/asm/exception.h +++ b/kernel/arch/aarch64/asm/exception.h @@ -16,6 +16,8 @@ // SPSR_EL3 #define SPSR_EL3_VAL ((7 << 6) | 5) +#define CPACR_FPEN 0x300000 + #ifdef __cplusplus extern "C" void setup_exception_level(); #endif \ No newline at end of file diff --git a/kernel/arch/aarch64/asm/startup.S b/kernel/arch/aarch64/asm/startup.S index 8c36948b..4bea6a53 100644 --- a/kernel/arch/aarch64/asm/startup.S +++ b/kernel/arch/aarch64/asm/startup.S @@ -11,8 +11,9 @@ start: cbnz x10, corestop // Get ourselves some stack - adrp x10, start - add x10, x10, :lo12:start + adrp x10, __early_stack + add x10, x10, :lo12:__early_stack + add x10, x10, #0x4000 mov sp, x10 // Clear out BSS diff --git a/kernel/arch/aarch64/kernel.ld b/kernel/arch/aarch64/kernel.ld index 4b7130ee..b1219b99 100644 --- a/kernel/arch/aarch64/kernel.ld +++ b/kernel/arch/aarch64/kernel.ld @@ -19,7 +19,7 @@ SECTIONS { .rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_BASE) { start_ctors = .; - *(.ctors) + *(.init_array) end_ctors = .; *(.rodata*) diff --git a/kernel/arch/aarch64/kstdio.cpp b/kernel/arch/aarch64/kstdio.cpp index babce441..16a1019b 100644 --- a/kernel/arch/aarch64/kstdio.cpp +++ b/kernel/arch/aarch64/kstdio.cpp @@ -4,5 +4,5 @@ #include "rpi/MiniUART.h" void serial_putch(char c) { - RPi::MiniUART::tx(c); +// RPi::MiniUART::tx(c); } \ No newline at end of file diff --git a/kernel/arch/aarch64/rpi/DeviceInfo.cpp b/kernel/arch/aarch64/rpi/DeviceInfo.cpp new file mode 100644 index 00000000..3ded770b --- /dev/null +++ b/kernel/arch/aarch64/rpi/DeviceInfo.cpp @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#include "DeviceInfo.h" +#include "Mailbox.h" + +#define MAILBOX_MEMORY_QUERY 0x10005 +#define MAILBOX + +using namespace RPi; + +DeviceInfo* DeviceInfo::s_inst = nullptr; + +DeviceInfo::DeviceInfo() { + // TODO: Query memory ranges +} + +DeviceInfo& DeviceInfo::inst() { + if (__builtin_expect(!s_inst, false)) + s_inst = new DeviceInfo(); + return *s_inst; +} + +size_t DeviceInfo::sdram_start() const { + return 0; +} + +size_t DeviceInfo::sdram_size() const { + return 0x20000000; // TODO: Actually query this +} + +size_t DeviceInfo::mmio_start() const { + // TODO: Other models + return 0x3F000000; +} + +size_t DeviceInfo::mmio_size() const { + return 0x01000000; +} + +DeviceInfo::Model DeviceInfo::model() const { + return DeviceInfo::RPi3b; +} diff --git a/kernel/arch/aarch64/rpi/DeviceInfo.h b/kernel/arch/aarch64/rpi/DeviceInfo.h new file mode 100644 index 00000000..3f27e9dc --- /dev/null +++ b/kernel/arch/aarch64/rpi/DeviceInfo.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#pragma once + +#include + +namespace RPi { + class DeviceInfo { + public: + static DeviceInfo& inst(); + + enum Model { + RPi3b + }; + + size_t sdram_start() const; + size_t sdram_size() const; + size_t mmio_start() const; + size_t mmio_size() const; + + Model model() const; + + private: + DeviceInfo(); + static DeviceInfo* s_inst; + }; +} diff --git a/kernel/arch/aarch64/startup.cpp b/kernel/arch/aarch64/startup.cpp index 002c9273..66a124d0 100644 --- a/kernel/arch/aarch64/startup.cpp +++ b/kernel/arch/aarch64/startup.cpp @@ -10,25 +10,40 @@ #include #include "asm/exception.h" #include "MMU.h" +#include +#include + +// TODO: We could unmap this once it's no longer needed. +__attribute__((aligned(8))) char __early_stack[0x4000]; + +[[noreturn]] void aarch64_late_init(); + +extern "C" int kmain(size_t mbootptr); extern "C" [[noreturn]] void aarch64init() { // We're currently mapped at a low physical address, so no touching any variables yet. setup_exception_level(); + // Init MMU Aarch64::MMU::mmu_init(); - while(1); // TODO + call_global_constructors(); + + // Jump to high memory and correct sp + asm volatile ( + "ldr x0, =1f \n" // Continue execution in high mem + "br x0 \n" + "1: \n" - // Setup MiniUART for output - RPi::MiniUART::init(); - RPi::MiniUART::puts("Booting, in el"); - RPi::MiniUART::tx('0' + get_el()); - RPi::MiniUART::tx('\n'); + "mov x0, sp \n" // OR high bits into sp + "mov x1, #" STR(HIGHER_HALF) "\n" + "orr x0, x0, x1 \n" + "mov sp, x0 \n" - RPi::Framebuffer::init(); - RPi::MiniUART::puts("Framebuffer inited!\n"); + "b kmain \n" // Jump to kinit + ::: "x0", "x1"); - while (1); + ASSERT(false); } extern "C" [[noreturn]] void unknown_el() { diff --git a/kernel/arch/i386/MemoryManager.cpp b/kernel/arch/i386/MemoryManager.cpp new file mode 100644 index 00000000..866d3e03 --- /dev/null +++ b/kernel/arch/i386/MemoryManager.cpp @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#include +#include +#include + +extern multiboot_info mboot_header; +extern multiboot_mmap_entry* mmap_entry; + +void MemoryManager::setup_device_memory_map() { + size_t mmap_offset = 0; + usable_bytes_ram = 0; + + auto make_region = [&](size_t addr, size_t size, bool reserved, bool used) { + //Round up the address of the entry to a page boundary and round the size down to a page boundary + uint32_t addr_pagealigned = ((addr + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; + uint32_t size_pagealigned = ((size - (addr_pagealigned - addr)) / PAGE_SIZE) * PAGE_SIZE; + + // We don't want the zero page. + if(addr_pagealigned == 0) { + addr_pagealigned += PAGE_SIZE; + if(size_pagealigned) + size_pagealigned -= PAGE_SIZE; + } + + if(size_pagealigned / PAGE_SIZE < 2) { + KLog::dbg("Memory", "Ignoring too-small memory region at {#x}", addr); + return; + } + + KLog::dbg("Memory", "Making memory region at page {#x} of {#x} pages ({}, {})", addr_pagealigned / PAGE_SIZE, + size_pagealigned / PAGE_SIZE, used ? "Used" : "Unused", reserved ? "Reserved" : "Unreserved"); + auto region = new PhysicalRegion( + addr_pagealigned / PAGE_SIZE, + size_pagealigned / PAGE_SIZE, + reserved, + used + ); + total_bytes_ram += size_pagealigned; + + if(addr_pagealigned < mem_lower_limit) + mem_lower_limit = addr_pagealigned; + if(addr_pagealigned + (size_pagealigned - 1) > mem_upper_limit) + mem_upper_limit = addr_pagealigned + (size_pagealigned - 1); + + if(!region->reserved()) + usable_bytes_ram += size_pagealigned; + else + reserved_bytes_ram += size_pagealigned; + + if(mmap_entry->type == MULTIBOOT_MEMORY_BADRAM) + bad_bytes_ram += size_pagealigned; + + m_physical_regions.push_back(region); + + KLog::dbg("Memory", "Adding memory region at page {#x} of {#x} pages ({}, {})", region->start_page(), + region->num_pages(), !region->free_pages() ? "Used" : "Unused", + region->reserved() ? "Reserved" : "Unreserved"); + }; + + while(mmap_offset < mboot_header.mmap_length) { + if(mmap_entry->addr_high || mmap_entry->len_high) { + //If the entry is in extended memory, ignore it + KLog::dbg("Memory", "Ignoring memory region above 4GiB (0x{x}{x})", + mmap_entry->addr_high, mmap_entry->addr_low); + } else { + size_t addr = mmap_entry->addr_low; + size_t size = mmap_entry->len_low; + size_t end = addr + size; + + // Check if the kernel is contained inside of this region. If so, we need to bifurcate it. + if(KERNEL_DATA_END - HIGHER_HALF >= addr && KERNEL_DATA_END - HIGHER_HALF <= end) { + KLog::dbg("Memory", "Kernel is from pages {#x} --> {#x}", (KERNEL_TEXT - HIGHER_HALF) / PAGE_SIZE, + (KERNEL_DATA_END - HIGHER_HALF) / PAGE_SIZE - 1); + if(addr < KERNEL_TEXT - HIGHER_HALF) { + // Space in region before kernel + make_region(addr, + KERNEL_TEXT - addr, + mmap_entry->type == MULTIBOOT_MEMORY_RESERVED, + mmap_entry->type != MULTIBOOT_MEMORY_AVAILABLE); + } + if(end > KERNEL_DATA_END - HIGHER_HALF) { + // Space in region after kernel + make_region(KERNEL_DATA_END - HIGHER_HALF, + end - (KERNEL_DATA_END - HIGHER_HALF), + mmap_entry->type == MULTIBOOT_MEMORY_RESERVED, + mmap_entry->type != MULTIBOOT_MEMORY_AVAILABLE); + } + } else { + make_region(addr, + size, + mmap_entry->type == MULTIBOOT_MEMORY_RESERVED, + mmap_entry->type != MULTIBOOT_MEMORY_AVAILABLE); + } + } + mmap_offset += mmap_entry->size + sizeof(mmap_entry->size); + mmap_entry = (struct multiboot_mmap_entry*) ((size_t)mmap_entry + mmap_entry->size + sizeof(mmap_entry->size)); + } + + KLog::dbg("Memory", "Total memory limits: {#x} -> {#x}", mem_lower_limit, mem_upper_limit); +} \ No newline at end of file diff --git a/kernel/arch/i386/PageDirectory.cpp b/kernel/arch/i386/PageDirectory.cpp new file mode 100644 index 00000000..fd2fbf1a --- /dev/null +++ b/kernel/arch/i386/PageDirectory.cpp @@ -0,0 +1,261 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#include "kernel/kstd/vector.hpp" +#include "kernel/tasking/TaskManager.h" +#include "kernel/kstd/defines.h" +#include "kernel/Atomic.h" +#include "kernel/memory/MemoryManager.h" +#include "kernel/kstd/KLog.h" +#include "kernel/KernelMapper.h" +#include "kernel/kstd/cstring.h" +#include +#include "PageTable.h" + +__attribute__((aligned(4096))) PageDirectory::Entry PageDirectory::s_kernel_entries[1024]; +PageTable PageDirectory::s_kernel_page_tables[256]; +__attribute__((aligned(4096))) PageTable::Entry s_kernel_page_table_entries[256][1024]; + +/** + * KERNEL MANAGEMENT + */ + +void PageDirectory::init_paging() { + // Clear the kernel page table entries + for(auto & entries : s_kernel_page_table_entries) + for(auto & entry : entries) + entry.value = 0; + + // Make the kernel's page tables + for(auto i = 0; i < 256; i++) { + new (&s_kernel_page_tables[i]) PageTable(HIGHER_HALF + i * PAGE_SIZE * 1024, false); + s_kernel_page_tables[i].entries() = s_kernel_page_table_entries[i]; + } + + // Clear out the kernel page directory entries below HIGHER_HALF + for(auto i = 0; i < 768; i++) + s_kernel_entries[i].value = 0; + + // Map the kernel page tables into the upper 1GiB of the page directory + for(auto i = 768; i < 1024; i++) { + s_kernel_entries[i].value = 0; + s_kernel_entries[i].data.present = true; + s_kernel_entries[i].data.read_write = true; + s_kernel_entries[i].data.user = false; + s_kernel_entries[i].data.set_address((size_t) s_kernel_page_tables[i - 768].entries() - HIGHER_HALF); + } + + setup_kernel_map(); + + // Enable paging + asm volatile( + "movl %%eax, %%cr3\n" //Put the page directory pointer in cr3 + "movl %%cr0, %%eax\n" + "orl $0x80000000, %%eax\n" //Set the proper flags in cr0 + "movl %%eax, %%cr0\n" + : : "a"((size_t) MM.kernel_page_directory.m_entries - HIGHER_HALF) + ); +} + +void PageDirectory::Entry::Data::set_address(size_t address) { + page_table_addr = address >> 12u; +} + +size_t PageDirectory::Entry::Data::get_address() { + return page_table_addr << 12u; +} + +/** + * PageDirectory stuff + */ + + +PageDirectory::PageDirectory(PageDirectory::DirectoryType type): + m_type(type) +{ + if(type == DirectoryType::USER) { + m_entries_region = MemoryManager::inst().alloc_contiguous_kernel_region(sizeof(Entry) * 1024); + m_entries = (Entry*) m_entries_region->start(); + // Map the kernel into the directory + for(auto i = 768; i < 1024; i++) { + m_entries[i].value = s_kernel_entries[i].value; + } + } else { + m_entries = s_kernel_entries; + } +} + +PageDirectory::~PageDirectory() { + if(m_type == DirectoryType::KERNEL) + PANIC("KERNEL_PAGETABLE_DELETED", "The kernel page directory was destroyed. Something has gone horribly wrong."); + + //Free page tables + for(auto & table : m_page_tables) + delete table; +} + +PageDirectory::Entry *PageDirectory::entries() { + return m_entries; +} + +size_t PageDirectory::entries_physaddr() { + return get_physaddr((size_t) m_entries); +} + +size_t PageDirectory::get_physaddr(size_t virtaddr) { + if(virtaddr < HIGHER_HALF) { //Program space + size_t page = virtaddr / PAGE_SIZE; + size_t directory_index = (page / 1024) % 1024; + if (!m_entries[directory_index].data.present) return -1; //TODO: Log an error + if (!m_page_tables[directory_index]) return -1; //TODO: Log an error + size_t table_index = page % 1024; + size_t page_paddr = (m_page_tables[directory_index])->entries()[table_index].data.get_address(); + return page_paddr + (virtaddr % PAGE_SIZE); + } else { //Kernel space + size_t page = (virtaddr) / PAGE_SIZE; + size_t directory_index = (page / 1024) % 1024; + if (!s_kernel_entries[directory_index].data.present) + return -1; //TODO: Log an error + size_t table_index = page % 1024; + size_t page_paddr = (s_kernel_page_table_entries[directory_index - 768])[table_index].data.get_address(); + return page_paddr + (virtaddr % PAGE_SIZE); + } +} + +size_t PageDirectory::get_physaddr(void *virtaddr) { + return get_physaddr((size_t)virtaddr); +} + +PageTable *PageDirectory::alloc_page_table(size_t tables_index) { + LOCK(m_lock); + + //If one was already allocated, return it + if(m_page_tables[tables_index]) + return m_page_tables[tables_index]; + + auto *table = new PageTable(tables_index * PAGE_SIZE * 1024, this); + m_page_tables[tables_index] = table; + PageDirectory::Entry *direntry = &m_entries[tables_index]; + direntry->data.set_address(get_physaddr(table->entries())); + direntry->data.present = true; + direntry->data.user = true; + direntry->data.read_write = true; + return table; +} + +void PageDirectory::dealloc_page_table(size_t tables_index) { + LOCK(m_lock); + if(!m_page_tables[tables_index]) + return; + delete m_page_tables[tables_index]; + m_page_tables[tables_index] = nullptr; + m_entries[tables_index].value = 0; +} + +bool PageDirectory::is_mapped(size_t vaddr, bool write) { + LOCK(m_lock); + if(vaddr < HIGHER_HALF) { //Program space + size_t page = vaddr / PAGE_SIZE; + size_t directory_index = (page / 1024) % 1024; + if (!m_entries[directory_index].data.present) return false; + if (!m_page_tables[directory_index]) return false; + auto& entry = m_page_tables[directory_index]->entries()[page % 1024]; + if(!entry.data.present) + return false; + if(write) { + if(!entry.data.read_write) + return false; + } + return true; + } else { //Kernel space + size_t page = (vaddr) / PAGE_SIZE; + size_t directory_index = (page / 1024) % 1024; + if (!s_kernel_entries[directory_index].data.present) + return false; + auto& entry = s_kernel_page_tables[directory_index - 768][page % 1024];; + return entry.data.present && (!write || entry.data.read_write); + } +} + +bool PageDirectory::is_mapped() { + size_t current_page_directory; + asm volatile("mov %%cr3, %0" : "=r"(current_page_directory)); + return current_page_directory == entries_physaddr(); +} + +Result PageDirectory::map_page(PageIndex vpage, PageIndex ppage, VMProt prot) { + size_t directory_index = (vpage / 1024) % 1024; + size_t table_index = vpage % 1024; + + PageTable::Entry* entry; + + if(directory_index < 768) { + // Userspace + if(m_type != DirectoryType::USER) { + KLog::warn("PageDirectory", "Tried mapping user in kernel directory!"); + return Result(EINVAL); + } + + //If the page table for this page hasn't been alloc'd yet, alloc it + if (!m_page_tables[directory_index]){ + alloc_page_table(directory_index); + } + + entry = &m_page_tables[directory_index]->entries()[table_index]; + if(!entry->data.present) + m_page_tables_num_mapped[directory_index]++; + } else { + // Kernel space + if(m_type != DirectoryType::KERNEL) { + KLog::warn("PageDirectory", "Tried mapping kernel in non-kernel directory!"); + return Result(EINVAL); + } + + entry = &s_kernel_page_tables[directory_index - 768].entries()[table_index]; + } + + entry->data.present = true; + entry->data.read_write = prot.write; + entry->data.user = directory_index < 768; + entry->data.set_address(ppage * PAGE_SIZE); + MemoryManager::inst().invlpg((void *) (vpage * PAGE_SIZE)); + + return Result(SUCCESS); +} + +Result PageDirectory::unmap_page(PageIndex vpage) { + size_t directory_index = (vpage / 1024) % 1024; + size_t table_index = vpage % 1024; + + if(directory_index < 768) { + // Userspace + if(m_type != DirectoryType::USER) { + KLog::warn("PageDirectory", "Tried mapping user in kernel directory!"); + return Result(EINVAL); + } + + //If the page table for this page hasn't been alloc'd yet, alloc it + if (!m_page_tables[directory_index]){ + alloc_page_table(directory_index); + } + + auto* entry = &m_page_tables[directory_index]->entries()[table_index]; + if(entry->data.present) + m_page_tables_num_mapped[directory_index]--; + entry->value = 0; + if(!m_page_tables_num_mapped[directory_index]) + dealloc_page_table(directory_index); + } else { + // Kernel space + if(m_type != DirectoryType::KERNEL) { + KLog::warn("PageDirectory", "Tried mapping kernel in non-kernel directory!"); + return Result(EINVAL); + } + + auto* entry = &s_kernel_page_tables[directory_index - 768].entries()[table_index]; + entry->value = 0; + } + + MemoryManager::inst().invlpg((void *) (vpage * PAGE_SIZE)); + return Result(SUCCESS); +} \ No newline at end of file diff --git a/kernel/memory/PageTable.cpp b/kernel/arch/i386/PageTable.cpp similarity index 94% rename from kernel/memory/PageTable.cpp rename to kernel/arch/i386/PageTable.cpp index 124199fe..20ec7b7b 100644 --- a/kernel/memory/PageTable.cpp +++ b/kernel/arch/i386/PageTable.cpp @@ -18,8 +18,8 @@ */ #include "PageTable.h" -#include "PageDirectory.h" -#include "MemoryManager.h" +#include "kernel/memory/PageDirectory.h" +#include "kernel/memory/MemoryManager.h" void PageTable::Entry::Data::set_address(size_t address) { page_addr = address >> 12u; diff --git a/kernel/memory/PageTable.h b/kernel/arch/i386/PageTable.h similarity index 95% rename from kernel/memory/PageTable.h rename to kernel/arch/i386/PageTable.h index b2b73d5c..cde46424 100644 --- a/kernel/memory/PageTable.h +++ b/kernel/arch/i386/PageTable.h @@ -19,8 +19,8 @@ #pragma once -#include -#include "VMRegion.h" +#include "kernel/kstd/types.h" +#include "kernel/memory/VMRegion.h" class PageDirectory; class PageTable { diff --git a/kernel/arch/i386/asm/startup.s b/kernel/arch/i386/asm/startup.s index c2f2b061..b0d2dd66 100644 --- a/kernel/arch/i386/asm/startup.s +++ b/kernel/arch/i386/asm/startup.s @@ -1,7 +1,7 @@ [bits 32] [global start] [global load_gdt] -[extern kmain] +[extern i386init] global flagss @@ -113,7 +113,7 @@ start_hh: mov esp, stack+0x4000 push dword [mbootptr] - call kmain + call i386init jmp $ diff --git a/kernel/arch/i386/device/Device.cpp b/kernel/arch/i386/device/Device.cpp index a67f72f8..00b6a23f 100644 --- a/kernel/arch/i386/device/Device.cpp +++ b/kernel/arch/i386/device/Device.cpp @@ -3,10 +3,22 @@ #include "kernel/device/I8042.h" #include "AC97Device.h" +#include "BochsVGADevice.h" +#include "kernel/device/MultibootVGADevice.h" + +extern multiboot_info mboot_header; void Device::arch_init() { I8042::init(); auto dev = AC97Device::detect(); if (!dev.is_error()) dev.value().leak_ref(); // Yes.. + + BochsVGADevice* bochs_vga = BochsVGADevice::create(); + if(!bochs_vga) { + //We didn't find a bochs VGA device, try using the multiboot VGA device + auto* mboot_vga = MultibootVGADevice::create(&mboot_header); + if(!mboot_vga || mboot_vga->is_textmode()) + PANIC("MBOOT_TEXTMODE", "duckOS doesn't support textmode."); + } } \ No newline at end of file diff --git a/kernel/arch/i386/startup.cpp b/kernel/arch/i386/startup.cpp new file mode 100644 index 00000000..15a77482 --- /dev/null +++ b/kernel/arch/i386/startup.cpp @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#include +#include +#include +#include +#include +#include + +multiboot_info mboot_header; +multiboot_mmap_entry* mmap_entry; + +struct multiboot_info parse_mboot(size_t physaddr); +extern uint8_t boot_disk; + +extern "C" void kmain(); + +extern "C" void i386init(uint32_t mbootptr) { + call_global_constructors(); + mboot_header = parse_mboot(mbootptr); + CommandLine cmd_line(mboot_header); + kmain(); + ASSERT(false); +} + +struct multiboot_info parse_mboot(size_t physaddr){ + auto* header = (struct multiboot_info*) (physaddr + HIGHER_HALF); + + //Check boot disk + if(header->flags & MULTIBOOT_INFO_BOOTDEV) { + boot_disk = (header->boot_device & 0xF0000000u) >> 28u; + KLog::dbg("kinit", "BIOS boot disk: {#x}", boot_disk); + } else { + PANIC("MULTIBOOT_FAIL", "The multiboot header doesn't have boot device info. Cannot boot."); + } + + //Parse memory map + if(header->flags & MULTIBOOT_INFO_MEM_MAP) { + mmap_entry = (multiboot_mmap_entry*) ((size_t) header->mmap_addr + HIGHER_HALF); + } else { + PANIC("MULTIBOOT_FAIL", "The multiboot header doesn't have a memory map. Cannot boot."); + } + + return *header; +} \ No newline at end of file diff --git a/kernel/constructors.cpp b/kernel/constructors.cpp new file mode 100644 index 00000000..c70d2c0c --- /dev/null +++ b/kernel/constructors.cpp @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#include "constructors.h" +#include "kstd/kstdio.h" + +typedef void (*constructor_func)(); +extern constructor_func start_ctors[]; +extern constructor_func end_ctors[]; + +//This method should be called with global constructors, so we'll assert that did_constructors == true after we do that +bool did_constructors = false; +__attribute__((constructor)) void constructor_test() { + did_constructors = true; +} + +void call_global_constructors() { + for (constructor_func* ctor = start_ctors; ctor < end_ctors; ctor++) + (*ctor)(); + ASSERT(did_constructors); +} \ No newline at end of file diff --git a/kernel/constructors.h b/kernel/constructors.h new file mode 100644 index 00000000..eee0f466 --- /dev/null +++ b/kernel/constructors.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ + +#pragma once + +void call_global_constructors(); \ No newline at end of file diff --git a/kernel/device/DiskDevice.cpp b/kernel/device/DiskDevice.cpp index 15c6b41e..3efedb07 100644 --- a/kernel/device/DiskDevice.cpp +++ b/kernel/device/DiskDevice.cpp @@ -17,7 +17,6 @@ Copyright (c) Byteduck 2016-2021. All rights reserved. */ -#include #include #include #include "DiskDevice.h" diff --git a/kernel/device/MultibootVGADevice.cpp b/kernel/device/MultibootVGADevice.cpp index ebe408d5..3388cbda 100644 --- a/kernel/device/MultibootVGADevice.cpp +++ b/kernel/device/MultibootVGADevice.cpp @@ -19,7 +19,6 @@ #include #include "MultibootVGADevice.h" -#include #include #include #include diff --git a/kernel/kmain.cpp b/kernel/kmain.cpp index 74e3f294..3cb299a2 100644 --- a/kernel/kmain.cpp +++ b/kernel/kmain.cpp @@ -47,58 +47,21 @@ #include "net/NetworkAdapter.h" #if defined(__i386__) -#include "arch/i386/device/BochsVGADevice.h" #include "arch/i386/device/PATADevice.h" #endif uint8_t boot_disk; -typedef void (*constructor_func)(); -extern constructor_func start_ctors[]; -extern constructor_func end_ctors[]; - -//This method should be called with global constructors, so we'll assert that did_constructors == true after we do that -bool did_constructors = false; -__attribute__((constructor)) void constructor_test() { - did_constructors = true; -} - -//Use a uint8_t array to store the memory manager, or else it would be re-initialized when global constructors are called -uint8_t __mem_manager_storage[sizeof(MemoryManager)] __attribute__((aligned(4096))); - -int kmain(size_t mbootptr){ - // Call global constructors - for (constructor_func* ctor = start_ctors; ctor < end_ctors; ctor++) - (*ctor)(); - ASSERT(did_constructors); - - clearScreen(); - KLog::info("kinit", "Starting duckOS..."); +void kmain(){ Processor::init(); - new (__mem_manager_storage) MemoryManager; + KLog::info("kinit", "Starting duckOS..."); - struct multiboot_info mboot_header = parse_mboot(mbootptr); - CommandLine cmd_line(mboot_header); Memory::init(); - MemoryManager::inst().setup_paging(); Processor::init_interrupts(); VMWare::detect(); Device::init(); - //Try setting up VGA -#if defined(__i386__) - BochsVGADevice* bochs_vga = BochsVGADevice::create(); - if(!bochs_vga) { - //We didn't find a bochs VGA device, try using the multiboot VGA device -#endif - auto* mboot_vga = MultibootVGADevice::create(&mboot_header); - if(!mboot_vga || mboot_vga->is_textmode()) - PANIC("MBOOT_TEXTMODE", "duckOS doesn't support textmode."); -#if defined(__i386__) - } -#endif - // Clear screen and draw boot logo clearScreen(); size_t logo_pos[2] = { @@ -117,8 +80,8 @@ int kmain(size_t mbootptr){ KLog::dbg("kinit", "First stage complete."); TaskManager::init(); + ASSERT(false); //We should never get here - return 0; } void kmain_late(){ @@ -258,25 +221,3 @@ void kmain_late(){ ASSERT(false); #endif } - -struct multiboot_info parse_mboot(size_t physaddr){ - auto* header = (struct multiboot_info*) (physaddr + HIGHER_HALF); - - //Check boot disk - if(header->flags & MULTIBOOT_INFO_BOOTDEV) { - boot_disk = (header->boot_device & 0xF0000000u) >> 28u; - KLog::dbg("kinit", "BIOS boot disk: {#x}", boot_disk); - } else { - PANIC("MULTIBOOT_FAIL", "The multiboot header doesn't have boot device info. Cannot boot."); - } - - //Parse memory map - if(header->flags & MULTIBOOT_INFO_MEM_MAP) { - auto* mmap_entry = (multiboot_mmap_entry*) ((size_t) header->mmap_addr + HIGHER_HALF); - MemoryManager::inst().parse_mboot_memory_map(header, mmap_entry); - } else { - PANIC("MULTIBOOT_FAIL", "The multiboot header doesn't have a memory map. Cannot boot."); - } - - return *header; -} diff --git a/kernel/kmain.h b/kernel/kmain.h index 59d76bad..f35b3cba 100644 --- a/kernel/kmain.h +++ b/kernel/kmain.h @@ -21,5 +21,5 @@ #include struct multiboot_info parse_mboot(size_t physaddr); -extern "C" int kmain(size_t mbootptr); +extern "C" void kmain(); void kmain_late(); diff --git a/kernel/memory/Memory.cpp b/kernel/memory/Memory.cpp index a8575e75..4a74fe73 100644 --- a/kernel/memory/Memory.cpp +++ b/kernel/memory/Memory.cpp @@ -2,9 +2,12 @@ /* Copyright © 2016-2023 Byteduck */ #include "Memory.h" +#include "MemoryManager.h" #if defined(__i386__) #include "kernel/arch/i386/gdt.h" +#elif defined(__aarch64__) +#include #endif const VirtualRange VirtualRange::null = {0, 0}; @@ -13,4 +16,6 @@ void Memory::init() { #if defined(__i386__) Memory::load_gdt(); #endif + MM.setup_device_memory_map(); + MM.setup_paging(); } \ No newline at end of file diff --git a/kernel/memory/Memory.h b/kernel/memory/Memory.h index 822931b3..dabaed10 100644 --- a/kernel/memory/Memory.h +++ b/kernel/memory/Memory.h @@ -34,7 +34,7 @@ extern "C" long _PAGETABLES_END; #define KERNEL_TEXT_SIZE (KERNEL_TEXT_END - KERNEL_TEXT) #define KERNEL_DATA_SIZE (KERNEL_DATA_END - KERNEL_DATA) #define KERNEL_END_VIRTADDR (HIGHER_HALF + KERNEL_SIZE_PAGES * PAGE_SIZE) -#define KERNEL_VIRTUAL_HEAP_BEGIN 0xE0000000 +#define KERNEL_VIRTUAL_HEAP_BEGIN (HIGHER_HALF + 0x20000000) #define MAX_QUICKMAP_PAGES 8 #define KERNEL_QUICKMAP_PAGES (KERNEL_VIRTUAL_HEAP_BEGIN - (PAGE_SIZE * MAX_QUICKMAP_PAGES)) diff --git a/kernel/memory/MemoryManager.cpp b/kernel/memory/MemoryManager.cpp index 878ce1c9..249a5032 100644 --- a/kernel/memory/MemoryManager.cpp +++ b/kernel/memory/MemoryManager.cpp @@ -19,9 +19,7 @@ #include #include -#include #include -#include "PageTable.h" #include "MemoryManager.h" #include #include "AnonymousVMObject.h" @@ -31,14 +29,6 @@ #include #include -size_t usable_bytes_ram = 0; -size_t total_bytes_ram = 0; -size_t reserved_bytes_ram = 0; -size_t bad_bytes_ram = 0; -size_t usable_lower_limt = ~0; -size_t usable_upper_limit = 0; -size_t mem_lower_limit = ~0; -size_t mem_upper_limit = 0; size_t used_kheap_mem; uint8_t early_kheap_memory[0x200000]; // 2MiB @@ -46,6 +36,7 @@ size_t used_early_kheap_memory = 0; bool did_setup_paging = false; MemoryManager* MemoryManager::_inst; +Mutex MemoryManager::s_liballoc_lock {"liballoc"}; kstd::Arc kernel_text_region; kstd::Arc kernel_data_region; kstd::Arc physical_pages_region; @@ -56,17 +47,15 @@ MemoryManager::MemoryManager(): { if(_inst) PANIC("MEMORY_MANAGER_DUPLICATE", "Something tried to initialize the memory manager twice."); - _inst = this; } MemoryManager& MemoryManager::inst() { + if(__builtin_expect(!_inst, false)) + _inst = new MemoryManager; return *_inst; } void MemoryManager::setup_paging() { - // Setup and enable paging - PageDirectory::init_paging(); - // Find a region where we can store our physical page array size_t num_physical_pages = mem_upper_limit / PAGE_SIZE; size_t page_array_num_pages = kstd::ceil_div(num_physical_pages * sizeof(PhysicalPage), PAGE_SIZE); @@ -96,6 +85,9 @@ void MemoryManager::setup_paging() { KLog::dbg("Memory", "Mapping physical page array to pages {#x} -> {#x}", page_array_start_page, page_array_start_page + page_array_num_pages - 1); + // Setup and enable paging + PageDirectory::init_paging(); + // Map the array to memory VMProt pages_prot = { .read = true, @@ -187,107 +179,6 @@ void MemoryManager::invlpg(void* vaddr) { // TODO: aarch64 } -void MemoryManager::parse_mboot_memory_map(struct multiboot_info* header, struct multiboot_mmap_entry* mmap_entry) { - size_t mmap_offset = 0; - usable_bytes_ram = 0; - - auto make_region = [&](size_t addr, size_t size, bool reserved, bool used) { - //Round up the address of the entry to a page boundary and round the size down to a page boundary - uint32_t addr_pagealigned = ((addr + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; - uint32_t size_pagealigned = ((size - (addr_pagealigned - addr)) / PAGE_SIZE) * PAGE_SIZE; - - // We don't want the zero page. - if(addr_pagealigned == 0) { - addr_pagealigned += PAGE_SIZE; - if(size_pagealigned) - size_pagealigned -= PAGE_SIZE; - } - - if(size_pagealigned / PAGE_SIZE < 2) { - KLog::dbg("Memory", "Ignoring too-small memory region at {#x}", addr); - return; - } - - KLog::dbg("Memory", "Making memory region at page {#x} of {#x} pages ({}, {})", addr_pagealigned / PAGE_SIZE, - size_pagealigned / PAGE_SIZE, used ? "Used" : "Unused", reserved ? "Reserved" : "Unreserved"); - auto region = new PhysicalRegion( - addr_pagealigned / PAGE_SIZE, - size_pagealigned / PAGE_SIZE, - reserved, - used - ); - total_bytes_ram += size_pagealigned; - - if(!region->reserved() && region->free_pages()) { - if(addr_pagealigned < usable_lower_limt) - usable_lower_limt = addr_pagealigned; - if(addr_pagealigned + (size_pagealigned - 1) > usable_upper_limit) - usable_upper_limit = addr_pagealigned + (size_pagealigned - 1); - } - - if(addr_pagealigned < mem_lower_limit) - mem_lower_limit = addr_pagealigned; - if(addr_pagealigned + (size_pagealigned - 1) > mem_upper_limit) - mem_upper_limit = addr_pagealigned + (size_pagealigned - 1); - - if(!region->reserved()) - usable_bytes_ram += size_pagealigned; - else - reserved_bytes_ram += size_pagealigned; - - if(mmap_entry->type == MULTIBOOT_MEMORY_BADRAM) - bad_bytes_ram += size_pagealigned; - - m_physical_regions.push_back(region); - - KLog::dbg("Memory", "Adding memory region at page {#x} of {#x} pages ({}, {})", region->start_page(), - region->num_pages(), !region->free_pages() ? "Used" : "Unused", - region->reserved() ? "Reserved" : "Unreserved"); - }; - - while(mmap_offset < header->mmap_length) { - if(mmap_entry->addr_high || mmap_entry->len_high) { - //If the entry is in extended memory, ignore it - KLog::dbg("Memory", "Ignoring memory region above 4GiB (0x{x}{x})", - mmap_entry->addr_high, mmap_entry->addr_low); - } else { - size_t addr = mmap_entry->addr_low; - size_t size = mmap_entry->len_low; - size_t end = addr + size; - - // Check if the kernel is contained inside of this region. If so, we need to bifurcate it. - if(KERNEL_DATA_END - HIGHER_HALF >= addr && KERNEL_DATA_END - HIGHER_HALF <= end) { - KLog::dbg("Memory", "Kernel is from pages {#x} --> {#x}", (KERNEL_TEXT - HIGHER_HALF) / PAGE_SIZE, - (KERNEL_DATA_END - HIGHER_HALF) / PAGE_SIZE - 1); - if(addr < KERNEL_TEXT - HIGHER_HALF) { - // Space in region before kernel - make_region(addr, - KERNEL_TEXT - addr, - mmap_entry->type == MULTIBOOT_MEMORY_RESERVED, - mmap_entry->type != MULTIBOOT_MEMORY_AVAILABLE); - } - if(end > KERNEL_DATA_END - HIGHER_HALF) { - // Space in region after kernel - make_region(KERNEL_DATA_END - HIGHER_HALF, - end - (KERNEL_DATA_END - HIGHER_HALF), - mmap_entry->type == MULTIBOOT_MEMORY_RESERVED, - mmap_entry->type != MULTIBOOT_MEMORY_AVAILABLE); - } - } else { - make_region(addr, - size, - mmap_entry->type == MULTIBOOT_MEMORY_RESERVED, - mmap_entry->type != MULTIBOOT_MEMORY_AVAILABLE); - } - } - mmap_offset += mmap_entry->size + sizeof(mmap_entry->size); - mmap_entry = (struct multiboot_mmap_entry*) ((size_t)mmap_entry + mmap_entry->size + sizeof(mmap_entry->size)); - } - - KLog::dbg("Memory", "Usable memory limits: {#x} -> {#x}", usable_lower_limt, usable_upper_limit); - KLog::dbg("Memory", "Total memory limits: {#x} -> {#x}", mem_lower_limit, mem_upper_limit); -} - ResultRet MemoryManager::alloc_physical_page() const { for(size_t i = 0; i < m_physical_regions.size(); i++) { auto result = m_physical_regions[i]->alloc_page(); @@ -502,11 +393,11 @@ size_t MemoryManager::kernel_heap() const { } void liballoc_lock() { - MemoryManager::inst().liballoc_lock.acquire(); + MemoryManager::s_liballoc_lock.acquire(); } void liballoc_unlock() { - MemoryManager::inst().liballoc_lock.release(); + MemoryManager::s_liballoc_lock.release(); } void *liballoc_alloc(int pages) { @@ -529,7 +420,8 @@ void *liballoc_alloc(int pages) { } void liballoc_afteralloc(void* ptr_alloced) { - MM.finalize_heap_pages(); + if (did_setup_paging) + MM.finalize_heap_pages(); } void liballoc_free(void *ptr, int pages) { diff --git a/kernel/memory/MemoryManager.h b/kernel/memory/MemoryManager.h index cf79243e..adf6c7d6 100644 --- a/kernel/memory/MemoryManager.h +++ b/kernel/memory/MemoryManager.h @@ -21,8 +21,6 @@ #include #include -#include "PageTable.h" -#include "PageDirectory.h" #include "PhysicalPage.h" #include "PhysicalRegion.h" #include "BuddyZone.h" @@ -30,6 +28,7 @@ #include #include "Memory.h" #include "kernel/arch/i386/registers.h" +#include /** * The basic premise of how the memory allocation in duckOS is as follows: @@ -64,11 +63,7 @@ class MemoryManager { public: PageDirectory kernel_page_directory { PageDirectory::DirectoryType::KERNEL }; - PageDirectory::Entry kernel_page_directory_entries[1024] __attribute__((aligned(4096))); - PageTable::Entry kernel_early_page_table_entries1[1024] __attribute__((aligned(4096))); - PageTable::Entry kernel_early_page_table_entries2[1024] __attribute__((aligned(4096))); - - Mutex liballoc_lock {"liballoc"}; + static Mutex s_liballoc_lock; MemoryManager(); @@ -220,9 +215,9 @@ class MemoryManager { void invlpg(void* vaddr); /** - * Parses the multiboot memory map. + * Sets up a memory map for the hardware. */ - void parse_mboot_memory_map(multiboot_info* header, multiboot_mmap_entry* first_entry); + void setup_device_memory_map(); /** * Allocates a number of new pages for the heap. `finalize_heap_pages` MUST be called afterwards to release the lock @@ -250,6 +245,13 @@ class MemoryManager { static MemoryManager* _inst; + size_t usable_bytes_ram = 0; + size_t total_bytes_ram = 0; + size_t reserved_bytes_ram = 0; + size_t bad_bytes_ram = 0; + size_t mem_lower_limit = ~0; + size_t mem_upper_limit = 0; + // Heap stuff kstd::vector m_heap_pages = kstd::vector(4096); size_t m_num_heap_pages; diff --git a/kernel/memory/PageDirectory.cpp b/kernel/memory/PageDirectory.cpp index b6ae3b20..5c3f1f86 100644 --- a/kernel/memory/PageDirectory.cpp +++ b/kernel/memory/PageDirectory.cpp @@ -1,147 +1,9 @@ -/* - This file is part of duckOS. +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2024 Byteduck */ - duckOS is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - duckOS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with duckOS. If not, see . - - Copyright (c) Byteduck 2016-2021. All rights reserved. -*/ - -#include -#include -#include -#include -#include -#include "PageTable.h" +#include "PageDirectory.h" #include "MemoryManager.h" -#include "kernel/kstd/KLog.h" -#include "../KernelMapper.h" -#include - -/* - * These variables are stored in char arrays in order to avoid re-initializing them when we call global constructors, - * as they will have already been initialized by init_kmem(). - */ -//__attribute__((aligned(4096))) uint8_t __kernel_page_table_entries_storage[sizeof(PageTable::Entry) * 256 * 1024]; -//uint8_t __kernel_entries_storage[sizeof(PageDirectory::Entry) * 256]; -//uint8_t __kernel_page_tables_storage[sizeof(PageTable) * 256]; - -__attribute__((aligned(4096))) PageDirectory::Entry PageDirectory::s_kernel_entries[1024]; -PageTable PageDirectory::s_kernel_page_tables[256]; -__attribute__((aligned(4096))) PageTable::Entry s_kernel_page_table_entries[256][1024]; - -/** - * KERNEL MANAGEMENT - */ - -void PageDirectory::init_paging() { - // Clear the kernel page table entries - for(auto & entries : s_kernel_page_table_entries) - for(auto & entry : entries) - entry.value = 0; - - // Make the kernel's page tables - for(auto i = 0; i < 256; i++) { - new (&s_kernel_page_tables[i]) PageTable(HIGHER_HALF + i * PAGE_SIZE * 1024, false); - s_kernel_page_tables[i].entries() = s_kernel_page_table_entries[i]; - } - - // Clear out the kernel page directory entries below HIGHER_HALF - for(auto i = 0; i < 768; i++) - s_kernel_entries[i].value = 0; - - // Map the kernel page tables into the upper 1GiB of the page directory - for(auto i = 768; i < 1024; i++) { - s_kernel_entries[i].value = 0; - s_kernel_entries[i].data.present = true; - s_kernel_entries[i].data.read_write = true; - s_kernel_entries[i].data.user = false; - s_kernel_entries[i].data.set_address((size_t) s_kernel_page_tables[i - 768].entries() - HIGHER_HALF); - } - - auto map_range = [&](VirtualAddress vstart, VirtualAddress pstart, size_t size, VMProt prot) { - size_t start_vpage = vstart / PAGE_SIZE; - size_t start_ppage = pstart / PAGE_SIZE; - size_t num_pages = ((vstart + size) / PAGE_SIZE) - start_vpage; - for(size_t i = 0; i < num_pages; i++) - if(MM.kernel_page_directory.map_page(start_vpage + i, start_ppage + i, prot).is_error()) - PANIC("PAGING_INIT_FAIL", "Could not map the kernel when setting up paging."); - }; - - // Map the kernel text and data - - map_range(KERNEL_TEXT, KERNEL_TEXT - HIGHER_HALF, KERNEL_TEXT_SIZE, VMProt::RX); - - map_range(KERNEL_DATA, KERNEL_DATA - HIGHER_HALF, KERNEL_DATA_SIZE, VMProt::RW); - - // Enable paging - -#if defined(__i386__) - asm volatile( - "movl %%eax, %%cr3\n" //Put the page directory pointer in cr3 - "movl %%cr0, %%eax\n" - "orl $0x80000000, %%eax\n" //Set the proper flags in cr0 - "movl %%eax, %%cr0\n" - : : "a"((size_t) MM.kernel_page_directory.m_entries - HIGHER_HALF) - ); -#endif - // TODO: aarch64 -} - -void PageDirectory::Entry::Data::set_address(size_t address) { - page_table_addr = address >> 12u; -} - -size_t PageDirectory::Entry::Data::get_address() { - return page_table_addr << 12u; -} - -/** - * PageDirectory stuff - */ - - -PageDirectory::PageDirectory(PageDirectory::DirectoryType type): - m_type(type) -{ - if(type == DirectoryType::USER) { - m_entries_region = MemoryManager::inst().alloc_contiguous_kernel_region(sizeof(Entry) * 1024); - m_entries = (Entry*) m_entries_region->start(); - // Map the kernel into the directory - for(auto i = 768; i < 1024; i++) { - m_entries[i].value = s_kernel_entries[i].value; - } - } else { - m_entries = s_kernel_entries; - } -} - -PageDirectory::~PageDirectory() { - if(m_type == DirectoryType::KERNEL) - PANIC("KERNEL_PAGETABLE_DELETED", "The kernel page directory was destroyed. Something has gone horribly wrong."); - - //Free page tables - for(auto & table : m_page_tables) - delete table; -} - -PageDirectory::Entry *PageDirectory::entries() { - return m_entries; -} - -size_t PageDirectory::entries_physaddr() { - return get_physaddr((size_t) m_entries); -} +#include void PageDirectory::map(VMRegion& region, VirtualRange range) { LOCK(m_lock); @@ -202,165 +64,18 @@ void PageDirectory::unmap(VMRegion& region, VirtualRange range) { } } -size_t PageDirectory::get_physaddr(size_t virtaddr) { - if(virtaddr < HIGHER_HALF) { //Program space - size_t page = virtaddr / PAGE_SIZE; - size_t directory_index = (page / 1024) % 1024; - if (!m_entries[directory_index].data.present) return -1; //TODO: Log an error - if (!m_page_tables[directory_index]) return -1; //TODO: Log an error - size_t table_index = page % 1024; - size_t page_paddr = (m_page_tables[directory_index])->entries()[table_index].data.get_address(); - return page_paddr + (virtaddr % PAGE_SIZE); - } else { //Kernel space - size_t page = (virtaddr) / PAGE_SIZE; - size_t directory_index = (page / 1024) % 1024; - if (!s_kernel_entries[directory_index].data.present) - return -1; //TODO: Log an error - size_t table_index = page % 1024; - size_t page_paddr = (s_kernel_page_table_entries[directory_index - 768])[table_index].data.get_address(); - return page_paddr + (virtaddr % PAGE_SIZE); - } -} - -size_t PageDirectory::get_physaddr(void *virtaddr) { - return get_physaddr((size_t)virtaddr); -} - -PageTable *PageDirectory::alloc_page_table(size_t tables_index) { - LOCK(m_lock); - - //If one was already allocated, return it - if(m_page_tables[tables_index]) - return m_page_tables[tables_index]; - - auto *table = new PageTable(tables_index * PAGE_SIZE * 1024, this); - m_page_tables[tables_index] = table; - PageDirectory::Entry *direntry = &m_entries[tables_index]; - direntry->data.set_address(get_physaddr(table->entries())); - direntry->data.present = true; - direntry->data.user = true; - direntry->data.read_write = true; - return table; -} - -void PageDirectory::dealloc_page_table(size_t tables_index) { - LOCK(m_lock); - if(!m_page_tables[tables_index]) - return; - delete m_page_tables[tables_index]; - m_page_tables[tables_index] = nullptr; - m_entries[tables_index].value = 0; -} - -bool PageDirectory::is_mapped(size_t vaddr, bool write) { - LOCK(m_lock); - if(vaddr < HIGHER_HALF) { //Program space - size_t page = vaddr / PAGE_SIZE; - size_t directory_index = (page / 1024) % 1024; - if (!m_entries[directory_index].data.present) return false; - if (!m_page_tables[directory_index]) return false; - auto& entry = m_page_tables[directory_index]->entries()[page % 1024]; - if(!entry.data.present) - return false; - if(write) { - if(!entry.data.read_write) - return false; - } - return true; - } else { //Kernel space - size_t page = (vaddr) / PAGE_SIZE; - size_t directory_index = (page / 1024) % 1024; - if (!s_kernel_entries[directory_index].data.present) - return false; - auto& entry = s_kernel_page_tables[directory_index - 768][page % 1024];; - return entry.data.present && (!write || entry.data.read_write); - } -} - -bool PageDirectory::is_mapped() { - size_t current_page_directory; -#if defined(__i386__) - asm volatile("mov %%cr3, %0" : "=r"(current_page_directory)); -#endif - // TODO: aarch64 - return current_page_directory == entries_physaddr(); -} - -Result PageDirectory::map_page(PageIndex vpage, PageIndex ppage, VMProt prot) { - size_t directory_index = (vpage / 1024) % 1024; - size_t table_index = vpage % 1024; - - PageTable::Entry* entry; - - if(directory_index < 768) { - // Userspace - if(m_type != DirectoryType::USER) { - KLog::warn("PageDirectory", "Tried mapping user in kernel directory!"); - return Result(EINVAL); - } - - //If the page table for this page hasn't been alloc'd yet, alloc it - if (!m_page_tables[directory_index]){ - alloc_page_table(directory_index); - } - - entry = &m_page_tables[directory_index]->entries()[table_index]; - if(!entry->data.present) - m_page_tables_num_mapped[directory_index]++; - } else { - // Kernel space - if(m_type != DirectoryType::KERNEL) { - KLog::warn("PageDirectory", "Tried mapping kernel in non-kernel directory!"); - return Result(EINVAL); - } - - entry = &s_kernel_page_tables[directory_index - 768].entries()[table_index]; - } - - entry->data.present = true; - entry->data.read_write = prot.write; - entry->data.user = directory_index < 768; - entry->data.set_address(ppage * PAGE_SIZE); - MemoryManager::inst().invlpg((void *) (vpage * PAGE_SIZE)); - - return Result(SUCCESS); -} - -Result PageDirectory::unmap_page(PageIndex vpage) { - size_t directory_index = (vpage / 1024) % 1024; - size_t table_index = vpage % 1024; - - if(directory_index < 768) { - // Userspace - if(m_type != DirectoryType::USER) { - KLog::warn("PageDirectory", "Tried mapping user in kernel directory!"); - return Result(EINVAL); - } - - //If the page table for this page hasn't been alloc'd yet, alloc it - if (!m_page_tables[directory_index]){ - alloc_page_table(directory_index); - } - - auto* entry = &m_page_tables[directory_index]->entries()[table_index]; - if(entry->data.present) - m_page_tables_num_mapped[directory_index]--; - entry->value = 0; - if(!m_page_tables_num_mapped[directory_index]) - dealloc_page_table(directory_index); - } else { - // Kernel space - if(m_type != DirectoryType::KERNEL) { - KLog::warn("PageDirectory", "Tried mapping kernel in non-kernel directory!"); - return Result(EINVAL); - } - - auto* entry = &s_kernel_page_tables[directory_index - 768].entries()[table_index]; - entry->value = 0; - } - - MemoryManager::inst().invlpg((void *) (vpage * PAGE_SIZE)); - return Result(SUCCESS); -} - +void PageDirectory::setup_kernel_map() { + // Manually map pages for kernel to start with. + auto map_range = [&](VirtualAddress vstart, VirtualAddress pstart, size_t size, VMProt prot) { + size_t start_vpage = vstart / PAGE_SIZE; + size_t start_ppage = pstart / PAGE_SIZE; + size_t num_pages = ((vstart + size) / PAGE_SIZE) - start_vpage; + for(size_t i = 0; i < num_pages; i++) + if(MM.kernel_page_directory.map_page(start_vpage + i, start_ppage + i, prot).is_error()) + PANIC("PAGING_INIT_FAIL", "Could not map the kernel when setting up paging."); + }; + // Map the kernel text and data + map_range(KERNEL_TEXT, KERNEL_TEXT - HIGHER_HALF, KERNEL_TEXT_SIZE, VMProt::RX); + map_range(KERNEL_DATA, KERNEL_DATA - HIGHER_HALF, KERNEL_DATA_SIZE, VMProt::RW); +} \ No newline at end of file diff --git a/kernel/memory/PageDirectory.h b/kernel/memory/PageDirectory.h index 23448f88..f5029674 100644 --- a/kernel/memory/PageDirectory.h +++ b/kernel/memory/PageDirectory.h @@ -25,6 +25,10 @@ #include "Memory.h" #include "VMRegion.h" +#if defined(__aarch64__) +#include +#endif + class PageTable; class PageDirectory { @@ -34,6 +38,15 @@ class PageDirectory { KERNEL }; + explicit PageDirectory(DirectoryType type = DirectoryType::USER); + ~PageDirectory(); + + /** + * Initialize the kernel page directory entries & related variables. + */ + static void init_paging(); + +#if defined(__i386__) typedef union Entry { class __attribute((packed)) Data { public: @@ -55,14 +68,6 @@ class PageDirectory { uint32_t value; } Entry; - /** - * Initialize the kernel page directory entries & related variables. - */ - static void init_paging(); - - explicit PageDirectory(DirectoryType type = DirectoryType::USER); - ~PageDirectory(); - /** * Gets a pointer to the entries in the PageDirectory. * @return @@ -74,6 +79,7 @@ class PageDirectory { * @return The physical address of the table of entries. */ size_t entries_physaddr(); +#endif /** * Maps a portion of a region into the page directory. @@ -101,19 +107,6 @@ class PageDirectory { */ size_t get_physaddr(void* virtaddr); - /** - * Allocates space for a new page table at tables_index in the page directory. - * @param tables_index The index in the page directory that this newly allocated page table is for. - * @return A pointer to the newly allocated page table. - */ - PageTable* alloc_page_table(size_t tables_index); - - /** - * Deallocates the space used for a page table at tables_index in the page directory. - * @param tables_index The index in the page directory of the page table being dealloc'd. - */ - void dealloc_page_table(size_t tables_index); - /** * Checks if a given virtual address is mapped to anything. * @param vaddr The virtual address to check. @@ -146,13 +139,29 @@ class PageDirectory { */ Result unmap_page(PageIndex vpage); + /** + * Maps the kernel when booting, without initializing VMRegions and tracking physical pages. + */ + static void setup_kernel_map(); + +#if defined(__i386__) + /** + * Allocates space for a new page table at tables_index in the page directory. + * @param tables_index The index in the page directory that this newly allocated page table is for. + * @return A pointer to the newly allocated page table. + */ + PageTable* alloc_page_table(size_t tables_index); + + /** + * Deallocates the space used for a page table at tables_index in the page directory. + * @param tables_index The index in the page directory of the page table being dealloc'd. + */ + void dealloc_page_table(size_t tables_index); + // The entries for the kernel. static Entry s_kernel_entries[1024]; // The page tables for the kernel. static PageTable s_kernel_page_tables[256]; - - // The type of the page directory. - const DirectoryType m_type; // The VMRegion for this page directory's entries. kstd::Arc m_entries_region; // The page directory entries for this page directory. @@ -161,6 +170,50 @@ class PageDirectory { PageTable* m_page_tables[768] = {nullptr}; // An array of u16s that stores the number of pages mapped in each page table, used to deallocate a page table once no longer needed int m_page_tables_num_mapped[1024] = {0}; +#elif defined(__aarch64__) + static uint64_t* alloc_table(); + + /* Yes, these could all be the same struct. + * However, this way, naming in code will be much clearer. */ + struct LowerPages { + Aarch64::MMU::PageDescriptor* entries; + }; + + template + struct Table { + Aarch64::MMU::TableDescriptor* entries = nullptr; + Child* children[512] = {nullptr}; + + Child* get_child(size_t index) { + ASSERT(index >= 0 && index < 512); + auto& child = children[index]; + if (__builtin_expect(!child, false)) { + child = new Child(); + child->entries = (typeof(child->entries)) alloc_table(); + entries[index].valid = true; + entries[index].type = Aarch64::MMU::TableDescriptor::Table; + // TODO: Actual physical page lookup + entries[index].address = Aarch64::MMU::descriptor_addr(((size_t) child->entries) & (~HIGHER_HALF)); + entries[index].heirarchical_perms = 0; + entries[index].security = Aarch64::MMU::TableDescriptor::Secure; + } + return child; + } + }; + + using MiddleTable = Table; + using UpperTable = Table; + using GlobalTable = Table; + + // The page global directory. + GlobalTable m_global_table; + + // The start page of the global directory. + PageIndex start_page; +#endif + + // The type of the page directory. + const DirectoryType m_type; // A lock used to prevent race conditions. Mutex m_lock {"PageDirectory"}; }; diff --git a/kernel/memory/VMSpace.h b/kernel/memory/VMSpace.h index c5199ae8..85f7a754 100644 --- a/kernel/memory/VMSpace.h +++ b/kernel/memory/VMSpace.h @@ -7,7 +7,7 @@ #include "VMRegion.h" #include "../Result.hpp" #include "../tasking/Mutex.h" -#include "PageDirectory.h" +#include #include /** diff --git a/kernel/tasking/ELF.cpp b/kernel/tasking/ELF.cpp index e7c9c13a..580f77e9 100644 --- a/kernel/tasking/ELF.cpp +++ b/kernel/tasking/ELF.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/kernel/tasking/Thread.cpp b/kernel/tasking/Thread.cpp index 54169e62..ad4035e2 100644 --- a/kernel/tasking/Thread.cpp +++ b/kernel/tasking/Thread.cpp @@ -397,13 +397,13 @@ void Thread::acquired_lock(Mutex* lock) { TaskManager::ScopedCritical crit; if(_held_locks.size() == _held_locks.capacity()) PANIC("MAX_LOCKS", "A thread is holding way too many locks."); - if(lock != &MM.liballoc_lock && lock != &TaskManager::g_tasking_lock) + if(lock != &MM.s_liballoc_lock && lock != &TaskManager::g_tasking_lock) _held_locks.push_back(lock); } void Thread::released_lock(Mutex* lock) { TaskManager::ScopedCritical crit; - if(lock != &MM.liballoc_lock && lock != &TaskManager::g_tasking_lock) { + if(lock != &MM.s_liballoc_lock && lock != &TaskManager::g_tasking_lock) { ASSERT(_held_locks.size()); // Ensure locks are acquired and released in the correct order auto last_held = _held_locks.pop_back(); diff --git a/kernel/tasking/Thread.h b/kernel/tasking/Thread.h index 18750932..a316fbbb 100644 --- a/kernel/tasking/Thread.h +++ b/kernel/tasking/Thread.h @@ -26,7 +26,7 @@ #include #include "kernel/memory/VMRegion.h" #include "Mutex.h" -#include "../memory/PageDirectory.h" +#include #include "../kstd/queue.hpp" #include "kernel/kstd/circular_queue.hpp" #include "../kstd/KLog.h" diff --git a/kernel/tests/TestMemory.cpp b/kernel/tests/TestMemory.cpp index 7e83b653..7a5593b4 100644 --- a/kernel/tests/TestMemory.cpp +++ b/kernel/tests/TestMemory.cpp @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-3.0-or-later */ /* Copyright © 2016-2022 Byteduck */ #include "KernelTest.h" -#include "../memory/PageDirectory.h" +#include #include "../random.h" #define NUM_REGIONS 100