global start global kernel_pml4 global kernel_pdpt_0 global kernel_pd_0 global kernel_pt_0 global paging_pt global bootstrap_pt extern kmain extern amd64_shim bits 32 section .multiboot align 8 mb_start: ; header dd 0xe85250d6 dd 0 dd mb_end - mb_start dd 0x100000000 - (0xe85250d6 + (mb_end - mb_start)) ; null tag dw 0 dw 0 dd 8 ; mb_end: section .bss align 4096 kernel_pml4: ; reserve memory for initial 512 pml4 entires resb 4096 kernel_pdpt_0: ; reserve memory for initial 512 pdpt entires resb 4096 kernel_pd_0: ; reserve memory for initial 512 pd entries resb 4096 kernel_pt_0: ; reserve memory for initial 512 pt entries resb 4096 paging_pt: ; reserve pages for pager mappings resb 4096 bootstrap_pt: ; reserve pages to bootstrap pager resb 4096 align 16 stack_start: resb 16384 stack_end: section .rodata align 16 ; Access bits PRESENT equ 1 << 7 NOT_SYS equ 1 << 4 EXEC equ 1 << 3 DC equ 1 << 2 RW equ 1 << 1 ACCESSED equ 1 << 0 ; Flags bits GRAN_4K equ 1 << 7 SZ_32 equ 1 << 6 LONG_MODE equ 1 << 5 GDT: .Null: equ $ - GDT dq 0 .Code: equ $ - GDT dd 0xFFFF ; Limit & Base (low, bits 0-15) db 0 ; Base (mid, bits 16-23) db PRESENT | NOT_SYS | EXEC | RW ; Access db GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19) db 0 ; Base (high, bits 24-31) .Data: equ $ - GDT dd 0xFFFF ; Limit & Base (low, bits 0-15) db 0 ; Base (mid, bits 16-23) db PRESENT | NOT_SYS | RW ; Access db GRAN_4K | SZ_32 | 0xF ; Flags & Limit (high, bits 16-19) db 0 ; Base (high, bits 24-31) .TSS: equ $ - GDT dd 0x00000068 dd 0x00CF8900 .Pointer: dw $ - GDT - 1 dq GDT section .text align 8 start: cli mov esp, stack_end mov ebp, stack_end push DWORD 0 push ebx mov edi, 0x1000 mov cr3, edi xor eax, eax mov ecx, 4096 rep stosd mov edi, cr3 mov DWORD [edi], kernel_pdpt_0 + 3 ; Set the uint32_t at the destination index to 0x2003. mov edi, kernel_pdpt_0 ; Add 0x1000 to the destination index. mov DWORD [edi], kernel_pd_0 + 3 ; Set the uint32_t at the destination index to 0x3003. mov edi, kernel_pd_0 ; Add 0x1000 to the destination index. mov DWORD [edi], kernel_pt_0 + 3 ; Set the uint32_t at the destination index to 0x4003. mov edi, kernel_pt_0 ; Add 0x1000 to the destination index. mov ebx, 0x00000003 ; Set the B-register to 0x00000003. mov ecx, 512 ; Set the C-register to 512. .SetEntry: mov DWORD [edi], ebx ; Set the uint32_t at the destination index to the B-register. add ebx, 0x1000 ; Add 0x1000 to the B-register. add edi, 8 ; Add eight to the destination index. loop .SetEntry ; Set the next entry. ;push ebx ; Call our function to set up basic paging ;call amd64_shim mov eax, cr4 ; Enable the PAE bit or eax, 1 << 5 mov cr4, eax mov ecx, 0xC0000080 ; Enable long mode rdmsr or eax, 1 << 8 wrmsr mov eax, cr0 ; Enable paging or eax, 1 << 31 mov cr0, eax lgdt [GDT.Pointer] jmp GDT.Code:code64 bits 64 code64: pop rdi call amd64_shim mov rdi, rax call kmain cli halt: hlt jmp halt