function for reading lba, get correct offset into sector for gpt entry

main
pantonshire 1 year ago
parent f52b659945
commit 4433200e23

@ -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

Loading…
Cancel
Save