From d43d7caf15a01dd9c2ef1d9e975df3ef7c4e9204 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 27 Sep 2024 06:02:49 -0400 Subject: wip: initial commit --- memory.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 memory.cpp (limited to 'memory.cpp') diff --git a/memory.cpp b/memory.cpp new file mode 100644 index 0000000..2cc15be --- /dev/null +++ b/memory.cpp @@ -0,0 +1,87 @@ +#include "textoutput.hpp" + +#include +#include + +struct PageDirectory +{ + static constexpr std::uint32_t NotPresent = 0x2; + + PageDirectory(): value(NotPresent) {} + PageDirectory(void *addr): value(reinterpret_cast(addr) | 3) {} + + std::uint32_t value; +}; +static_assert(sizeof(PageDirectory) == sizeof(std::uint32_t)); + +extern std::uint32_t lowerMem; +extern std::uint32_t upperMem; +extern TextOutput& term; + +static std::uintptr_t lowerFree = 0x400; +static std::uintptr_t upperFree = 0x100000; + +alignas(4096) +static std::array pageDirectory; + +alignas(4096) +static std::array pageTable; + +void memory_initialize() +{ + lowerMem -= 1024; + + const auto totalKb = (lowerMem + upperMem) / 1024u; + + term.write("Claiming "); + term.write(totalKb); + term.write(" kB for allocations...\n"); + + std::uint32_t addr = 0; + for (auto& p : pageTable) { + p = addr | 3; // supervisor, r/w, present + addr += 0x1000; + } + + pageDirectory[0] = PageDirectory(pageTable.data()); + + asm volatile(R"( + mov %%eax, %%cr3 + mov %%cr0, %%eax + or $0x80000000, %%eax + mov %%eax, %%cr0 + )" :: "a"(pageDirectory.data())); + + term.write("Paging enabled.\n"); +} + +static void *memory_alloc(std::size_t size) +{ + void *ret = nullptr; + + if (lowerMem > size) { + ret = reinterpret_cast(lowerFree); + lowerFree += size; + lowerMem -= size; + } else if (upperMem > size) { + ret = reinterpret_cast(upperFree); + upperFree += size; + upperMem -= size; + } else { + // Uh oh! + term.write("!!! Kernel allocation failed !!!"); + } + + return ret; +} + +void *operator new(std::size_t size) +{ + return memory_alloc(size); +} + +void *operator new[](std::size_t size) +{ + return memory_alloc(size); +} + -- cgit v1.2.3