|
|
|
|
@ -46,6 +46,15 @@ bits 16
|
|
|
|
|
mov bp, 0x7c00
|
|
|
|
|
mov sp, bp
|
|
|
|
|
|
|
|
|
|
; Segment for VGA (0xb800 * 16 = 0xb8000)
|
|
|
|
|
mov ax, 0xb800
|
|
|
|
|
mov fs, ax
|
|
|
|
|
|
|
|
|
|
; Set VGA mode
|
|
|
|
|
; https://mendelson.org/wpdos/videomodes.txt
|
|
|
|
|
mov ax, 0x0003
|
|
|
|
|
int 0x10
|
|
|
|
|
|
|
|
|
|
; Store boot drive number
|
|
|
|
|
xor dh, dh
|
|
|
|
|
push dx
|
|
|
|
|
@ -65,27 +74,11 @@ bits 16
|
|
|
|
|
push bx
|
|
|
|
|
|
|
|
|
|
; Load LBA 1.
|
|
|
|
|
cmp cl, 1 ; Division of 1 by nonzero can be done with cmp
|
|
|
|
|
sete al ; temp = LBA / (sectors per track)
|
|
|
|
|
setne cl ; sector - 1 = LBA % (sectors per track)
|
|
|
|
|
inc cl
|
|
|
|
|
xor ah, ah ; Zero-extend temp
|
|
|
|
|
xor dx, dx ; div by 16-bit register divides dx:ax, so we zero dx
|
|
|
|
|
div bx ; dx = mod (head), ax = div (cylinder)
|
|
|
|
|
|
|
|
|
|
mov dh, dl ; Head
|
|
|
|
|
mov ch, al ; Cylinder
|
|
|
|
|
; We already have sector in cl
|
|
|
|
|
mov ah, 2 ; Read disk
|
|
|
|
|
mov al, 1 ; Load one sector
|
|
|
|
|
mov ax, 1
|
|
|
|
|
mov bx, 0x7e00
|
|
|
|
|
mov dl, [bp - 0x2] ; Drive number
|
|
|
|
|
int 0x13
|
|
|
|
|
jc .panic
|
|
|
|
|
|
|
|
|
|
; head = temp % number of heads
|
|
|
|
|
; cylinder = temp / number of heads
|
|
|
|
|
call .read_lba
|
|
|
|
|
|
|
|
|
|
; Check the GPT header magic "EFI PART"
|
|
|
|
|
mov cx, 8
|
|
|
|
|
mov si, .gpt_magic
|
|
|
|
|
mov di, 0x7e00
|
|
|
|
|
@ -188,40 +181,30 @@ bits 16
|
|
|
|
|
mov word [bp - 0x14], 0 ; Reset the current entry index within the current sector
|
|
|
|
|
.load_first_lba:
|
|
|
|
|
mov ax, [bp - 0x18] ; Load current LBA
|
|
|
|
|
xor dx, dx
|
|
|
|
|
div word [bp - 0x04] ; Divide by sectors per track. dx = mod (sector - 1), ax = div (temp)
|
|
|
|
|
mov cx, dx
|
|
|
|
|
inc cx ; Put sector into cx (bios will read sector from cl)
|
|
|
|
|
xor dx, dx
|
|
|
|
|
div word [bp - 0x06] ; Divide by number of heads. dx = mod (head), ax = div (cylinder)
|
|
|
|
|
mov dh, dl
|
|
|
|
|
mov ch, al
|
|
|
|
|
mov dl, byte [bp - 0x02] ; Load drive number
|
|
|
|
|
mov ah, 0x02
|
|
|
|
|
mov al, 1
|
|
|
|
|
mov bx, 0x8000
|
|
|
|
|
int 0x13 ; Read sector
|
|
|
|
|
jc .panic
|
|
|
|
|
mov bx, 0x8000 ; Read sector just past end of the GPT header so we can keep it around
|
|
|
|
|
call .read_lba
|
|
|
|
|
inc word [bp - 0x16] ; Increment number of sectors loaded
|
|
|
|
|
|
|
|
|
|
.process_current_entry:
|
|
|
|
|
jmp .debug
|
|
|
|
|
; TODO
|
|
|
|
|
; TODO: remember to read offset by current entry index within the current sector
|
|
|
|
|
mov ax, [bp - 0x14] ; Load current entry index within current sector
|
|
|
|
|
xor dx, dx
|
|
|
|
|
mul word [bp - 0x0e] ; Get the byte offset in the current sector of the current entry
|
|
|
|
|
add ax, 0x8000 ; Convert offset to address (we loaded the sector at 0x8000)
|
|
|
|
|
|
|
|
|
|
mov cx, 16 ; GUID is 16 bytes
|
|
|
|
|
mov si, .guid_linux
|
|
|
|
|
mov di, ax
|
|
|
|
|
repe cmpsb
|
|
|
|
|
je .found_stage2
|
|
|
|
|
|
|
|
|
|
; Next iteration
|
|
|
|
|
inc word [bp - 0x12] ; Increment current entry index
|
|
|
|
|
inc word [bp - 0x14] ; Increment current entry index within the current sector
|
|
|
|
|
jmp .loop_find_stage2
|
|
|
|
|
|
|
|
|
|
.debug:
|
|
|
|
|
; Segment for VGA (0xb800 * 16 = 0xb8000)
|
|
|
|
|
mov ax, 0xb800
|
|
|
|
|
mov fs, ax
|
|
|
|
|
|
|
|
|
|
; Set VGA mode
|
|
|
|
|
; https://mendelson.org/wpdos/videomodes.txt
|
|
|
|
|
mov ax, 0x0003
|
|
|
|
|
int 0x10
|
|
|
|
|
.found_stage2:
|
|
|
|
|
; TODO: we've found the right entry, now we need to parse it, load the sector and jump to it
|
|
|
|
|
push ax ; address of the GPT entry for stage 2
|
|
|
|
|
|
|
|
|
|
mov al, [0x7e00]
|
|
|
|
|
mov byte fs:[0x0000], al
|
|
|
|
|
@ -229,17 +212,40 @@ bits 16
|
|
|
|
|
mov al, [0x8000]
|
|
|
|
|
mov byte fs:[0x0002], al
|
|
|
|
|
|
|
|
|
|
; mov word fs:[0x0000], 0xc048
|
|
|
|
|
; mov word fs:[0x0002], 0xc069
|
|
|
|
|
|
|
|
|
|
hlt
|
|
|
|
|
|
|
|
|
|
; Load a single boot disk sector. Panic on failure.
|
|
|
|
|
; Inputs:
|
|
|
|
|
; - ax: LBA to load
|
|
|
|
|
; - bx: address to read sector to
|
|
|
|
|
; Clobber: ax, cx, dx. Possibly bx? TODO: double check
|
|
|
|
|
; ngl probably best to assume everything is clobbered because it's a bios interrupt
|
|
|
|
|
.read_lba:
|
|
|
|
|
; sector - 1 = LBA % sectors_per_track
|
|
|
|
|
; temp = LBA / sectors_per_track
|
|
|
|
|
; head = temp % n_heads
|
|
|
|
|
; cylinder = temp / n_heads
|
|
|
|
|
xor dx, dx
|
|
|
|
|
; FIXME: we should probably get our globals from somewhere else, in case we want to change bp for
|
|
|
|
|
; a function call
|
|
|
|
|
div word [bp - 0x04] ; Divide by sectors per track. dx = mod (sector - 1), ax = div (temp)
|
|
|
|
|
mov cx, dx
|
|
|
|
|
inc cx ; Put sector into cx (bios will read sector from cl)
|
|
|
|
|
xor dx, dx
|
|
|
|
|
div word [bp - 0x06] ; Divide by number of heads. dx = mod (head), ax = div (cylinder)
|
|
|
|
|
mov dh, dl
|
|
|
|
|
mov ch, al
|
|
|
|
|
mov dl, byte [bp - 0x02] ; Load drive number
|
|
|
|
|
mov ah, 0x02
|
|
|
|
|
mov al, 1
|
|
|
|
|
int 0x13 ; Read sector
|
|
|
|
|
jc .panic
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.panic:
|
|
|
|
|
mov ax, 0x0003
|
|
|
|
|
int 0x10
|
|
|
|
|
mov ax, 0xb800
|
|
|
|
|
mov ds, ax
|
|
|
|
|
mov word [0x0000], 0x4f21
|
|
|
|
|
mov word fs:[0x0000], 0x4f21
|
|
|
|
|
hlt
|
|
|
|
|
|
|
|
|
|
; TODO: enable A20
|
|
|
|
|
|