工作FAT16 Bootloader会在实际硬件上产生读取错误吗?

Kyl*_*acy 6 x86 assembly nasm bootloader

在过去的一周里,我一直在开发一个简单的操作系统用于学习目的和......"有趣".虚拟盒和NASM,我实际上开始了一个非常好的开始.最后,我决定通过臭名昭着的Brokenthorn教程,直到从文件系统加载,我还想开发一个引导加载程序(在点击512字节的墙之后很难).

有了一些HexFiend恶作剧和一些空白的FAT16图像,我最终得到了BPB.通过一些额外的程序集hackery(基础是Brokenthorn的教程,第6部分),我还使用我的bootloader进行文件加载,它从我的虚拟磁盘加载适当命名的'boot'文件(使用dd if =/dev/zero of = boot.img bs = 512 count = 2880)

那么,问题是什么呢?当我通过USB记忆棒(在这种情况下,/ dev/disk3,其中编译的文件是boot.bin)加载到实际硬件时,我看到的是:

dd bs=512 count=1 if=compiled/boot.bin of=/dev/disk3
Run Code Online (Sandbox Code Playgroud)

这是预期的输出(在VirtualBox中):

电流输出

实际输出相比(在旧笔记本电脑上)

老输出

'-' indicates a sector is being loaded
'_' indicates a sector was loaded
'!' indicates all of the desired sectors were loaded properly
'R' indicates a read error
'T' indicates the FAT table is being loaded
'D' indicates the FAT table was loaded properly
'F' means the file is being located (or Found, hence the F)
'L' means the file is being loaded
Run Code Online (Sandbox Code Playgroud)

(我会使用实际的调试消息,但512字节的限制是非常可怕的.)

所以,区别在于一个是USB记忆棒,一个是(虚拟)软盘.它们都具有完全相同的信息,包括BPB.然而,一个工作,一个不工作.这是我加载扇区的代码的主要部分(使用啊02h/int 13h,我听说它适用于USB):

ReadSectors:
    mov di, 0x0005                  ; How many times should we retry the read?

ReadSectors.loop:
    ; DEBUG
    push ax
    mov ah, 0eh
    mov al, '-'
    int 10h
    pop ax
    push ax
    push bx
    push cx
    call LBAToCHS
    mov ah, 02h                     ; Set the interrupt to the 
                                    ; 'read sector' function
    mov al, 1                       ; Only read one sector
    mov ch, byte[chs.track]         ; The track to read from
    mov cl, byte[chs.sector]        ; The sector to read from
    mov dh, byte[chs.head]          ; The head to read from
    mov dl, byte[_bpb.driveNumber]  ; The drive to read from
    int 13h                         ; Call our 'disk IO' interrupt
    jnc ReadSectors.success         ; If we successfully read the data, 
                                    ; we don't have to try again
    mov ah, 00h                     ; Set the interrupt to the 
                                    ; 'reset disk' function
    int 13h                         ; Call our 'disk IO' interrupt
    dec di                          ; Decrement our error counter
    pop cx
    pop bx
    pop ax
    jnz ReadSectors.loop            ; Try again if we've failed
    jmp ReadSectors.fail            ; RED ALERT
Run Code Online (Sandbox Code Playgroud)

(可以在Pastebin上找到完整的源代码,包括BPB(http://pastebin.com/SeUm7xu6)

到目前为止,我已经克服了大会上的一些问题,但这个问题令我难过.希望我能够尽快通过引导加载程序并抽象文件IO.

任何建议将不胜感激.提前致谢!

Paw*_*pak 6

您的代码从0号驱动器中读取,这可能不是设备引导加载程序的加载(如果从USB引导程序启动,通常不会).您应该读取的驱动器号由BIOS加载到dl寄存器中.这已经是SO 的回答问题了.