diff --git a/boot0.s b/boot0.s index bd3a8f9..7a631ea 100644 --- a/boot0.s +++ b/boot0.s @@ -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