main.asm
1 global start 2 extern long_mode_start 3 4 section .text 5 bits 32 6 start: 7 mov esp, stack_top 8 9 call check_multiboot 10 call check_cpuid 11 call check_long_mode 12 13 call setup_page_tables 14 call enable_paging 15 16 lgdt [gdt64.pointer] 17 jmp gdt64.code_segment:long_mode_start 18 19 check_multiboot: 20 cmp eax, 0x36d76289 21 jne .no_multiboot 22 ret 23 .no_multiboot: 24 mov al, "M" 25 jmp error 26 27 check_cpuid: 28 pushfd 29 pop eax 30 mov ecx, eax 31 xor eax, 1 << 21 32 push eax 33 popfd 34 pushfd 35 pop eax 36 push ecx 37 popfd 38 cmp eax, ecx 39 je .no_cpuid 40 ret 41 .no_cpuid: 42 mov al, "C" 43 jmp error 44 45 check_long_mode: 46 mov eax, 0x80000000 47 cpuid 48 cmp eax, 0x80000001 49 jb .no_long_mode 50 51 mov eax, 0x80000001 52 cpuid 53 test edx, 1 << 29 54 jz .no_long_mode 55 ret 56 .no_long_mode: 57 mov al, "L" 58 jmp error 59 60 setup_page_tables: 61 mov eax, page_table_l3 62 or eax, 0b11 ; present, writable 63 mov [page_table_l4], eax 64 65 mov eax, page_table_l2 66 or eax, 0b11 ; present, writable 67 mov [page_table_l3], eax 68 69 mov ecx, 0 ; counter 70 .loop: 71 mov eax, 0x200000 ; 2MiB 72 mul ecx 73 or eax, 0b10000011 ; present, writeable, huge page 74 mov [page_table_l2 + ecx * 8], eax 75 76 inc ecx ; increment counter 77 cmp cx, 512 ; checks if the whole table is mapped 78 jne .loop ; if not, continue 79 80 ret 81 82 enable_paging: 83 ; pass page table location to cpu 84 mov eax, page_table_l4 85 mov cr3, eax 86 87 ; enable PAE 88 mov eax, cr4 89 or eax, 1 << 5 90 mov cr4, eax 91 92 ; enable long mode 93 mov ecx, 0xC0000080 94 rdmsr 95 or eax, 1 << 8 96 wrmsr 97 98 ; enable paging 99 mov eax, cr0 100 or eax, 1 << 31 101 mov cr0, eax 102 103 ret 104 105 error: 106 ; print "ERR: X" where X is the error code 107 mov dword [0xb8000], 0x4f524f45 108 mov dword [0xb8004], 0x4f3a4f52 109 mov dword [0xb8008], 0x4f204f20 110 mov byte [0xb800a], al 111 hlt 112 113 section .bss 114 align 4096 115 page_table_l4: 116 resb 4096 117 page_table_l3: 118 resb 4096 119 page_table_l2: 120 resb 4096 121 stack_bottom: 122 resb 4096 * 4 123 stack_top: 124 125 section .rodata 126 gdt64: 127 dq 0 ; zero entry 128 .code_segment: equ $ - gdt64 129 dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment 130 .pointer: 131 dw $ - gdt64 - 1 132 dq gdt64