mbr.asm (2582B)
1 bits 16 2 org 0x7c00 3 4 _start: 5 ; Disable interrupts to relocate 6 cli 7 8 ; Direction forward 9 cld 10 11 ; Clear the segments 12 xor ax, ax 13 mov ds, ax 14 mov es, ax 15 mov fs, ax 16 mov gs, ax 17 mov ss, ax 18 mov esp, 0x2000 19 20 ; Enable A20 21 in al, 0x92 22 or al, 0x02 23 out 0x92, al 24 25 ; Allocate load header 26 sub sp, 32 + 16 27 mov ebp, esp 28 29 ; Extended Read 30 lea si, [bp + 32] 31 mov dword [si + 0], 0x00100010 ; descriptor size and block count 32 mov dword [si + 4], 0x00002000 ; buffer address and segment 33 mov dword [si + 8], 1 ; lba 34 mov dword [si + 12], 0 35 mov ah, 0x42 36 mov dl, 0x80 37 int 0x13 38 39 ; Parse the header 40 mov edi, 0x00002000 41 mov cx, 0x800 42 .next_magic: 43 mov eax, 0x1badb002 44 repne scasd 45 cmp cx, 8 46 jb fail 47 add eax, [di] 48 add eax, [di + 4] 49 test eax, eax 50 jnz .next_magic 51 52 ; Check the header has load fields 53 test word [di + 4], 1 54 jz fail 55 56 ; Copy the header to bp 57 xor esi, esi 58 lea si, [di - 4] 59 mov di, bp 60 mov cx, 8 61 rep movsd 62 63 ; load_offset = si - 0x2020 + load_addr - header_addr 64 mov eax, [bp + 16] 65 sub eax, [bp + 12] 66 add eax, esi 67 sub eax, 0x2020 68 69 ; Check load_offset < 8k 70 mov ecx, 0x2000 71 sub ecx, eax 72 jb fail 73 74 ; Copy first page 75 mov edi, [bp + 16] 76 mov esi, 0x2000 77 add esi, eax 78 79 .copy_page: 80 a32 rep movsb 81 cmp edi, [bp + 20] 82 jae .load_done 83 84 lea si, [bp + 32] 85 add dword [si + 8], 16 86 mov ah, 0x42 87 mov dl, 0x80 88 int 0x13 89 90 mov esi, 0x2000 91 mov ecx, 0x2000 92 jmp .copy_page 93 .load_done: 94 95 ; Boot info header 96 sub sp, 128 97 mov ebp, esp 98 mov dword [bp], 0x40 99 100 ; Find the memory map 101 xor ebx, ebx 102 mov edi, 0x2100 103 mov [bp + 48], edi 104 add edi, 4 105 .next_mmap: 106 mov edx, 0x534d4150 107 mov eax, 0xe820 108 mov ecx, 20 109 int 0x15 110 mov edx, 0x534d4150 111 cmp eax, edx 112 jnz fail 113 mov [di - 4], ecx 114 add dword [bp + 44], 24 115 add di, 24 116 test ebx, ebx 117 jnz .next_mmap 118 119 ; Create GDT 120 mov esi, 0x2000 121 ; Null segment 122 mov dword [si + 0], 0 123 mov dword [si + 4], 0 124 ; Code segment 125 mov dword [si + 8], 0x0000ffff 126 mov dword [si + 12], 0x00cf9b00 127 ; Data segment 128 mov dword [si + 16], 0x0000ffff 129 mov dword [si + 20], 0x00cf9300 130 131 ; Load the GDT 132 sub sp, 6 133 mov edi, esp 134 mov word [di + 0], 23 135 mov dword [di + 2], esi 136 lgdt [edi] 137 add sp, 6 138 139 ; Enter protected mode 140 cli 141 mov eax, cr0 142 or al, 1 143 mov cr0, eax 144 jmp 8:_prot 145 bits 32 146 147 fail: 148 hlt 149 jmp fail 150 151 _prot: 152 ; Load protected segments 153 mov ax, 16 154 mov ds, ax 155 mov es, ax 156 mov fs, ax 157 mov gs, ax 158 mov ss, ax 159 mov esp, esp 160 161 ; Jump to the kernel 162 mov eax, 0x2badb002 163 mov ebx, ebp 164 mov edx, [bp + 28 + 128] 165 jmp edx 166 167 times (446 - ($ - _start)) db 0x90 168 169 ; Partition table 170 times (510 - ($ - _start)) db 0x00 171 ; Signature 172 db 0x55 173 db 0xaa