#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); }