6

この1週間ほど、学習目的でシンプルなOSを開発してきました...「楽しい」。VirtualBoxとNASMを牽引して、私は実際にかなり良いスタートを切った。最終的に、ファイルシステムからロードするまで、悪名高いBrokenthornチュートリアルを実行して、ブートローダーも開発したいと思いました(512バイトの壁にかなり激しくぶつかった後) 。

いくつかのHexFiendシェナニガンといくつかの空白のFAT16画像を使用して、最終的にBPBを機能させました。いくつかの追加のアセンブリハッカリー(基本はBrokenthornのチュートリアル、パート6)を使用して、仮想ディスク(dd if = / dev / zeroを使用して作成)から適切な名前の「boot」ファイルをロードするブートローダーでファイルのロードを実行しました。 of = boot.img bs = 512 count = 2880)

では、問題は何ですか?これは、USBスティック(この場合、コンパイルされたファイルがboot.binである/ dev / disk3)を介して実際のハードウェアにロードしたときに表示されるものです。

dd bs=512 count=1 if=compiled/boot.bin of=/dev/disk3

期待される出力は次のとおりです(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

(実際のデバッグメッセージを使用したはずですが、512バイトの制限はかなり厄介です。)

つまり、違いは、1つはUSBスティックで、もう1つは(仮想)フロッピーディスクであるということです。どちらも、BPBを含め、それぞれにまったく同じ情報がロードされています。ただし、1つは機能し、もう1つは機能しません。セクターをロードするための私のコードの主要部分は次のとおりです(USBで正しく機能すると聞いたah 02h / int 13hを使用):

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

(BPBを含む完全なソースは、Pastebin(http://pastebin.com/SeUm7xu6)にあります。

私はこれまでにAssemblyに関する多くの問題を克服してきましたが、これは私を困惑させました。うまくいけば、私はブートローダーを通り越して、できるだけ早くファイルIOを抽象化することができます。

任意の提案をいただければ幸いです。前もって感謝します!

4

1 に答える 1

6

コードは、ブートローダーがロードされたデバイスではない可能性のあるドライブ番号0から読み取ります(USBスティックから起動する場合はそうではないことがよくあります)。読み取る必要のあるドライブ番号は、BIOSによってdlレジスタにロードされます。それはすでにSOに関する回答済みの質問です。

于 2012-04-04T10:46:30.543 に答える