diff --git a/boot0.s b/boot0.s index 847b8c4..cd98039 100644 --- a/boot0.s +++ b/boot0.s @@ -4,10 +4,6 @@ ; R | 0x000000 - 0x000400: real-mode interrupt vector table ; R | 0x000400 - 0x000500: bios data area ; U | 0x000500 - 0x007c00: stack -; U | 0x007000 - 0x007c00: big stage0 initial stack frame -; | 0x007000 - 0x007001: boot drive number -; | 0x007001 - 0x007002: boot drive sectors per track -; | 0x007002 - 0x007004: boot drive number of heads ; U | 0x007c00 - 0x007e00: boot sector ; U | 0x007e00 - 0x080000: conventional usable memory ; R | 0x080000 - 0x0a0000: extended bios data area (maximum possible size) @@ -16,6 +12,15 @@ ; R | 0x0c8000 - 0x0f0000: bios expansiosn ; R | 0x0f0000 - 0x100000: motherboard bios +; BASE STACK FRAME +; -------------------------------------------------------------------- +; bp - 0x02: drive number +; bp - 0x04: sectors per track +; bp - 0x06: number of heads +; bp - 0x08: partition array starting LBA +; bp - 0x0a: number of GPT partitions (saturated to 16-bits) +; bp - 0x0c: sector stride when loading GPT entries + ; BIOS puts our boot sector at 0000:7c00 org 0x7c00 ; We're (probably) in real mode @@ -29,46 +34,50 @@ bits 16 mov ds, ax mov es, ax - ; We put stack base at 0x7c00 and give ourselves a big stack frame [0x7000,0x7c00) for spilling to. + ; Put the stack base at 0x7c00. ; Stack grows high->low, so we'll grow away from our program text at 0x7c00. mov ss, ax - mov sp, 0x7c00 - mov bp, 0x7000 + mov bp, 0x7c00 + mov sp, bp ; Segment for VGA (0xb800 * 16 = 0xb8000) mov ax, 0xb800 mov fs, ax ; Store boot drive number - mov [bp], dl + xor dh, dh + push dx ; Get drive geometry mov di, 0x00 mov ah, 0x08 int 0x13 jc .panic - and cl, 0x3f ; sectors per track - mov [bp + 1], cl + ; Load sectors per track into cx & spill + and cl, 0x3f + xor ch, ch + push cx + ; Load number of heads into bx & spill movzx bx, dh - inc bx ; number of heads - mov [bp + 2], bx + inc bx + push bx ; Load LBA 1. - cmp cl, 1 ; division of 1 by nonzero can be done with cmp + 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 ah, ah ; Zero-extend temp xor dx, dx ; div by 16-bit register divides dx:ax, so we zero dx div bx ; ah = mod (head), al = div (cylinder) - mov dh, ah ; head - mov ch, al ; cylinder - ; we already have sector in cl - mov ah, 2 ; read disk - mov al, 1 ; load one sector + mov dh, ah ; Head + mov ch, al ; Cylinder + ; We already have sector in cl + mov ah, 2 ; Read disk + mov al, 1 ; Load one sector mov bx, 0x7e00 - mov dl, [bp] ; drive number + mov dl, [bp - 0x2] ; Drive number int 0x13 jc .panic @@ -86,8 +95,8 @@ bits 16 repe cmpsb jne .panic - ; Ensure the 8-byte starting LBA fits in 16 bits - mov di, 0x7e00 ; the rep increments di so we need to reset it + ; Ensure the 8-byte GPT starting LBA fits in 16 bits + mov di, 0x7e00 ; The rep increments di so we need to reset it xor bx, bx mov ax, [di + 0x4a] or bx, ax @@ -96,11 +105,48 @@ bits 16 mov ax, [di + 0x4e] or bx, ax jnz .panic - + ; Load and spill the GPT starting LBA mov ax, [di + 0x48] - - mov word fs:[0x0000], 0xc048 - mov word fs:[0x0002], 0xc069 + push ax + + ; Load number of partitions + mov ax, [di + 0x50] + mov bx, [di + 0x52] + or bx, bx + jz .gpt_n_partitions_loaded + mov ax, 0xff ; Number of partitions overflows 16 bits +.gpt_n_partitions_loaded: + push ax + + ; Load GPT entry size + mov ax, [di + 0x54] + mov bx, [di + 0x56] + mov cx, ax + mov dx, bx + ; Find number of sectors per entry + shr ax, 9 + shr bx, 9 + or bx, bx + jnz .panic ; Sectors per entry overflows 16 bits + mov bx, ax + cmp bx, 1 + jnz .gpt_sector_stride_loaded + inc bx ; Sector stride must be at least one or we'll load the same sector forever! +.gpt_sector_stride_loaded: + push bx + + ; ax stores sectors per entry + ; FIXME: if sectors per entry > 1, then entry size must be a multiple of sector size + + mov al, [0x7e00] + mov byte fs:[0x0000], al + mov al, [0x7e01] + mov byte fs:[0x0002], al + mov al, [0x7e02] + mov byte fs:[0x0004], al + + ; mov word fs:[0x0000], 0xc048 + ; mov word fs:[0x0002], 0xc069 hlt