os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

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