find byte stride and entries per sector
This commit is contained in:
1 parent
a4fc5c6352
commit
694c7bf819
1 file changed
+45
-14
@@ -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,26 +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
|
||||||
|
|
||||||
|
cmp ebx, 512
|
||||||
|
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:
|
||||||
|
|
||||||
; ax stores sectors per entry
|
; ax stores sectors per entry
|
||||||
; FIXME: if sectors per entry > 1, then entry size must be a multiple of sector size
|
; FIXME: if sectors per entry > 1, then entry size must be a multiple of sector size
|
||||||
|
|||||||
Reference in new issue
Block a user