#include "cpu/memlayout.h" /* Memory layout at this point (see https://wiki.osdev.org/Memory_Map_(x86) for more details): 0x00500 - 0x08fff: usable memory 0x09000 – 0x14fff: kernel code and global data 0x15000 - 0x7ffff: usable memory 0x80000 - 0xfffff: BDA and upper memory 0x100000 - 0x8000000 (1 MiB - 128 MiB): usable memory */ .intel_syntax noprefix .global _start .asciz "kernel start\n" _start: .code32 mov dword ptr [patch_addr - KERNBASE], offset gdt32_begin - KERNBASE lgdt gdtr32 - KERNBASE // zero our PD at 0x1000 and PT at 0x2000 xor eax, eax mov ecx, 2048 rep stosd // Set up the page table for the lowest 4 MiB: PD[0] -> PT mov dword ptr [0x1000], 0x2000 | 0x3 // KERNBASE = 0xF000_0000 // Use the same page table for the first 4 MiB after KERNBASE: PD[0x3c0] -> PT mov dword ptr [0x1000 + (0x3c0 * 4)], 0x2000 | 0x3 // Identity map the first 2 MiB mov edi, 0x2000 // Start of the PT mov ebx, 0x00000003 // Present, R/W mov ecx, 512 // 2 MiB / 4 KiB = 512 SetEntry: mov dword ptr [edi], ebx add ebx, 0x1000 add edi, 4 loop SetEntry // Load physical address of PD into CR3 mov edi, 0x1000 mov cr3, edi // Enable paging mov eax, cr0 or eax, 1 << 31 // Set the PG bit mov cr0, eax .att_syntax jmp $0x8, $loadseg - KERNBASE .intel_syntax noprefix loadseg: // jump to the high half add esp, KERNBASE lea eax, kmain jmp eax .align 16 gdtr32: .word gdt32_end - gdt32_begin - 1 patch_addr: .long gdt32_begin - KERNBASE .align 16 gdt32_begin: .long 0x00000000, 0x00000000 # Null descriptor .long 0x0000ffff, 0x00cf9a00 # Code segment .long 0x0000ffff, 0x00cf9200 # Data segment gdt32_end: