find byte stride and entries per sector

main
pantonshire 1 year ago
parent a4fc5c6352
commit debcfdd281

@ -20,6 +20,8 @@
; bp - 0x08: partition array starting LBA ; bp - 0x08: partition array starting LBA
; bp - 0x0a: number of GPT partitions (saturated to 16-bits) ; bp - 0x0a: number of GPT partitions (saturated to 16-bits)
; bp - 0x0c: sector stride when loading GPT entries ; bp - 0x0c: sector stride when loading GPT entries
; bp - 0x0e: byte stride when loading GPT entries
; bp - 0x10: entries per sector when loding GPT entries
; BIOS puts our boot sector at 0000:7c00 ; BIOS puts our boot sector at 0000:7c00
org 0x7c00 org 0x7c00
@ -114,29 +116,55 @@ bits 16
mov bx, [di + 0x52] mov bx, [di + 0x52]
or bx, bx or bx, bx
jz .gpt_n_partitions_loaded jz .gpt_n_partitions_loaded
mov ax, 0xff ; Number of partitions overflows 16 bits ; Number of partitions overflows 16 bits, so we just concern ourselves with the first 65535.
; That's an awful lot of partitions anyway.
mov ax, 0xffff
.gpt_n_partitions_loaded: .gpt_n_partitions_loaded:
push ax push ax
; Load GPT entry size ; Load GPT entry size
mov ax, [di + 0x54] mov eax, [di + 0x54] ; Operand size override otherwise this is going to be painful
mov bx, [di + 0x56] mov ebx, eax
mov cx, ax ; Assert that the entry size is 128 * 2^n for some integer n>=0. This is required for a valid GPT
mov dx, bx ; and has the nice properties that:
; Find number of sectors per entry ; - If each entry is larger than a sector (512 bytes), they'll be sector-aligned.
shr ax, 9 ; - If each entry is smaller than a sector, an integer number of them will fit into a sector.
shr bx, 9 or eax, eax ; Test size != 0 because 128 * 2^n != 0
or bx, bx jz .panic
jnz .panic ; Sectors per entry overflows 16 bits and eax, 127 ; Test size is a multiple of 128
mov bx, ax jnz .panic
cmp bx, 1 mov eax, ebx
shr eax, 7 ; Divide by 128
mov ecx, eax
dec eax
and eax, ecx ; Test size/128 is a power of 2. popcnt gives an exception for some reason...
jnz .panic
mov eax, ebx
; Find the "sector stride", which is the number of sectors we increment by each time we want to
; load a new entry.
shr eax, 9 ; Divide by sector size to get sectors per entry
cmp eax, 0xffff ; Make sure sectors per entry fits in 16 bits
ja .panic
or ax, ax
jnz .gpt_sector_stride_loaded jnz .gpt_sector_stride_loaded
inc bx ; Sector stride must be at least one or we'll load the same sector forever! ; Sector stride must be at least one or we'll load the same sector each time!
inc ax
.gpt_sector_stride_loaded: .gpt_sector_stride_loaded:
push bx push ax
; ax stores sectors per entry cmp ebx, 512
; FIXME: if sectors per entry > 1, then entry size must be a multiple of sector size jb .gpt_find_entries_per_sector
push word 0 ; Arbitrary byte stride since there's only one entry per sector
push word 1 ; 1 entry per sector, since an entry is larger than a sector
jmp .gpt_found_entries_per_sector
.gpt_find_entries_per_sector:
push bx ; Store byte stride = entry length in this case
xor dx, dx
mov ax, 512
div bx ; Find entries per sector
push ax
.gpt_found_entries_per_sector:
mov al, [0x7e00] mov al, [0x7e00]
mov byte fs:[0x0000], al mov byte fs:[0x0000], al

Loading…
Cancel
Save