x86 BIOS启动加载器中LBA转CHS函数在LBA>65时失效问题排查
问题:x86 BIOS启动加载器LBA转CHS函数的溢出问题
我正在开发一款x86 BIOS启动加载器,第一阶段启动加载器(MBR)需要从磁盘读取2880个或更多扇区,随后跳转到位于磁盘第二个扇区的第二阶段启动加载器。第二阶段将通过FAT16加载内核文件,该部分我会后续实现。
目前LBA转CHS函数仅对小于65的LBA值有效,此范围足以加载用C语言编写的第二阶段。我已定义BPB_SecPerTrk为18,BPB_NumHeads为2。
以下是LBA转CHS转换函数的汇编代码:
; convert LBA to CHS ; input: si = LBA ; output: ch = cylinder, dh = head, cl = sector lba_to_chs: push bx ; save bx mov ax, si ; load LBA address into ax ; Calculate sectors (CL) xor dx, dx ; clear dx div word [BPB_SecPerTrk] ; ax = LBA / SPT, dx = LBA % SPT mov cl, dl ; cl = (LBA % SPT) + 1 (sector) inc cl ; increment cl by 1 ; Calculate head (DH) xor dx, dx ; clear dx div word [BPB_NumHeads] ; ax = LBA / (SPT * NumHeads), dx = (LBA / SPT) % NumHeads mov dh, dl ; dh = (LBA / SPT) % NumHeads (head) ; Calculate cylinder (CH) mov ch, al ; ch = ax (cylinder number, lower 8 bits) mov al, ah ; al = ah (upper 8 bits of cylinder number) shl al, 6 ; shift upper 2 bits of cylinder to higher bits or ch, al ; combine them with lower 8 bits of ch pop bx ; restore bx ret
以及磁盘初始化函数代码:
disk_init_lba: pusha ; check if lba extension is supperted mov ah, 0x41 ; check extensions mov bx, 0x55AA ; magic number mov dl, 0x80 ; disk number int 0x13 ; call BIOS stc ; DEBUG: implicitly disable reading disk using int 0x13 extensions jc .lba_ext_not_sup ; if carry flag flag is set, jump to error handler jmp .read_lba_ext ; if not, jump to read disk using LBA .read_lba_ext: mov si, DAPACK ; load DAP address to si mov ah, 0x42 ; extended read function mov dl, 0x80 ; disk number int 0x13 ; call BIOS jc .fail ; if carry flag is set, jump to error handler jmp .ok ; if not, jump to success handler .lba_ext_not_sup: call print_disk_lba_sup_fail ; print failure message jmp .read_lba_via_chs ; jump to read disk using CHS .read_lba_via_chs: clc ; clear carry flag if for some reason it was set xor si, si ; LBA = 0 xor di, di ; set di to 0 mov bx, START_STAGE1 ; buffer for sector jmp .loop ; jump to loop .loop: inc si ; increment LBA add bx, 0x200 ; next sector buffer call lba_to_chs ; convert LBA to CHS mov ah, 0x02 ; read disk BIOS function mov al, 0x01 ; number of sectors to read mov dl, 0x80 ; disk number 0 int 0x13 ; call BIOS jc .retry ; if carry flag is set, jump to error handler ; FIXME: reading LBAs above 65 ; TODO: read up to 1.44 MB (2879 sectors) cmp si, 65 ; check if we read enough sectors to fill 1.44 MB jle .loop ; if true read next sector jmp .ok ; if not, jump to success handler .retry: inc di ; increment di cmp di, 3 ; check if we tried 3 times jne .loop ; if not, retry jmp .fail ; if yes, jump to error handler .fail: call print_disk_read_fail ; print failure message jmp .exit ; jump to exit .ok: call print_disk_read_ok ; print success message jmp .exit ; jump to exit .exit: popa ret
我怀疑问题源于代码中的值溢出。
内容的提问来源于stack exchange,提问作者mtrzc0
相关产品推荐
相关产品推荐

