essence-os/boot/x86/mbr-emu.s

149 lines
2.4 KiB
ArmAsm

; This file is part of the Essence operating system.
; It is released under the terms of the MIT license -- see LICENSE.md.
; Written by: nakst.
[bits 16]
[org 0x600]
start:
; Setup segment registers and the stack
cli
mov ax,0
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov sp,0x7C00
sti
; Clear the screen
mov ax,0
int 0x10
mov ax,3
int 0x10
; Relocate to 0x600
cld
mov si,0x7C00
mov di,0x600
mov cx,0x200
rep movsb
jmp 0x0:find_partition
find_partition:
; Save the drive number
mov byte [drive_number],dl
; Get drive parameters.
mov ah,0x08
xor di,di
int 0x13
mov si,error_cannot_read_disk
jc error
and cx,63
mov [max_sectors],cx
inc dh
shr dx,8
mov [max_heads],dx
mov si,error_bad_geometry
or cx,cx
jz error
or dx,dx
jz error
; Find the bootable flag (0x80)
mov bx,partition_entry_1
cmp byte [bx],0x80
je found_partition
mov bx,partition_entry_2
cmp byte [bx],0x80
je found_partition
mov bx,partition_entry_3
cmp byte [bx],0x80
je found_partition
mov bx,partition_entry_4
cmp byte [bx],0x80
je found_partition
; No bootable partition
mov si,error_no_bootable_partition
jmp error
found_partition:
; Load the first sector of the partition at 0x7C00
push bx
mov di,[bx + 8]
mov bx,0x7C00
call load_sector
; Jump to the partition's boot sector
mov dl,[drive_number]
pop si
mov dh,0x01
jmp 0x0:0x7C00
error:
; Print an error message
lodsb
or al,al
jz .break
mov ah,0xE
int 0x10
jmp error
; Break indefinitely
.break:
cli
hlt
; di - LBA.
; es:bx - buffer
load_sector:
; Calculate cylinder and head.
mov ax,di
xor dx,dx
div word [max_sectors]
xor dx,dx
div word [max_heads]
push dx ; remainder - head
mov ch,al ; quotient - cylinder
shl ah,6
mov cl,ah
; Calculate sector.
mov ax,di
xor dx,dx
div word [max_sectors]
inc dx
or cl,dl
; Load the sector.
pop dx
mov dh,dl
mov dl,[drive_number]
mov ax,0x0201
int 0x13
mov si,error_cannot_read_disk
jc error
ret
error_cannot_read_disk: db "Error: The disk could not be read. (MBR)",0
error_no_bootable_partition: db "Error: No bootable partition could be found on the disk.",0
error_bad_geometry: db 'Error: The BIOS reported invalid disk geometry.',0
drive_number: db 0
max_sectors: dw 0
max_heads: dw 0
times (0x1B4 - ($-$$)) nop
disk_identifier: times 10 db 0
partition_entry_1: times 16 db 0
partition_entry_2: times 16 db 0
partition_entry_3: times 16 db 0
partition_entry_4: times 16 db 0
dw 0xAA55