#include #include #define PG_PRESENT 0x0000'0000'0000'0001 #define PG_READ_WRITE 0x0000'0000'0000'0002 #define PG_USER_SUPERVISE 0x0000'0000'0000'0004 #define PG_WRITE_THROUGH 0x0000'0000'0000'0008 #define PG_CACHE_DISABLE 0x0000'0000'0000'0010 #define PG_ACCESSED 0x0000'0000'0000'0020 #define PG_EXECUTE_DISABLE 0x8000'0000'0000'0000 #define F_PRESENT 0b1 #define F_WRITEABLE 0b10 #define F_UNPRIVILEGED 0b100 #define F_WRITETHROUGH 0b1000 #define F_CACHEDISABLE 0b10000 #define F_ACCESSED 0b100000 #define F_DIRTY 0b1000000 #define F_MEGABYTE 0b10000000 #define F_GLOBAL 0b100000000 // PAGE MAP LEVEL 4 ENTRY struct pml4e { uint64_t flags : 6; uint64_t _reserved : 6; uint64_t address : 40; uint64_t _reserved_2 : 11; uint64_t execute_disable : 1; }; // PAGE DIRECTORY POINTER TABLE ENTRY struct pdpte { uint64_t flags : 6; uint64_t _reserved : 1; uint64_t page_size : 1; uint64_t _reserved_2 : 2; uint64_t address : 40; uint64_t _reserved_3 : 11; uint64_t execute_disable : 1; }; // PAGE DIRECTORY ENTRY struct pde { uint64_t flags : 6; uint64_t _reserved : 1; uint64_t page_size : 1; uint64_t _reserved_2 : 2; uint64_t address : 40; uint64_t _reserved_3 : 11; uint64_t execute_disable : 1; }; // PAGE TABLE ENTRY struct pte { uint64_t flags : 9; uint64_t _reserved : 3; uint64_t address : 40; uint64_t _reserved_2 : 7; uint64_t protection_key : 4; uint64_t execute_disable : 1; }; struct pml4e pml4[512]; struct pdpte pdpt[512]; struct pde pd[512]; struct pte pt[512]; static int get_maxphysaddr() { uint32_t eax, ebx, ecx, edx; __cpuid(0x80000008, eax, ebx, ecx, edx); return eax & 0xFF; } // entry point for amd64 void* amd64_shim(void *boot_info) { for (int i = 0; i < 512; i++) { pml4[i].flags = 0; } for (int i = 0; i < 512; i++) { pdpt[i].flags = 0; } for (int i = 0; i < 512; i++) { pd[i].flags = 0; } pml4[0].flags = F_PRESENT | F_WRITEABLE; pml4[0].address = (uint64_t)&pdpt; pdpt[0].flags = F_PRESENT | F_WRITEABLE; pdpt[0].address = (uint64_t)&pd; pd[0].flags = F_PRESENT | F_WRITEABLE; pd[0].address = (uint64_t)&pt; for (int i = 0; i < 512; i++) { pt[i].flags = F_PRESENT | F_WRITEABLE; pt[i].address = i * 4096; } }