mirror of https://gitlab.com/nakst/essence
149 lines
2.4 KiB
ArmAsm
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
|