6

プロジェクトの場合、DOSから直接最初のハードディスクでMBRを呼び出したいと思います。私は0:7c00hにメモリにMBRをロードし、それにはるかにジャンプする小さなアセンブラプログラムを作成しました。utilを(DOS)起動可能なフロッピーに入れました。起動しようとしているディスク(HD0、0x80)には、TrueCryptブートローダーがあります。この設定でツールを実行すると、TrueCrypt画面が表示されますが、パスワードを入力するとシステムがクラッシュします。通常のWinXPマシンで小さなユーティリティ(w00t.com)を実行すると、すぐにクラッシュするようです。

どうやら私はBIOSが通常行ういくつかの重要なことを忘れているようです、私の推測ではそれは些細なことです。ベアメタルDOSとBIOSの経験が豊富な人が私を助けてくれますか?

これが私のコードです:

.MODEL tiny
.386
_TEXT SEGMENT USE16

INCLUDE BootDefs.i

ORG 100h

start:
    ; http://vxheavens.com/lib/vbw05.html
    ; Before DOS has booted the BIOS stores the amount of usable lower memory 
    ; in a word located at 0:413h in memory. We going to erase this value because
    ; we have booted dos before loading the bootsector, and dos is fat (and ugly).

    ; fake free memory  
    ;push ds
    ;push   0
    ;pop        ds
    ;mov        ax, TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
    ;mov    word ptr ds:[413h], ax  ;ax = memory in K
    ;pop ds
    ;lea si, memory_patched_msg
    ;call print

    ;mov ax, cs
    mov ax, 0
    mov es, ax

    ; read first sector to es:7c00h (== cs:7c00)
    mov  dl, 80h
    mov  cl, 1
    mov  al, 1
    mov  bx, 7c00h ;load sector to es:bx
    call read_sectors

    lea si, mbr_loaded_msg
    call print

    lea si, jmp_to_mbr_msg
    call print

    ;Set BIOS default values in environment
    cli
    mov dl, 80h ;(drive C)
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0ffffh
    sti

    push es
    push 7c00h
    retf            ;Jump to MBR code at 0:7c00h


    ; Print string
print:
    xor bx, bx
    mov ah, 0eh
    cld

@@: lodsb
    test al, al
    jz print_end

    int 10h
    jmp @B

print_end:
    ret

    ; Read sectors of the first cylinder
read_sectors:
    mov ch, 0           ; Cylinder
    mov dh, 0           ; Head
                        ; DL = drive number passed from BIOS
    mov ah, 2
    int 13h
    jnc read_ok

    lea si, disk_error_msg
    call print
read_ok:
    ret

memory_patched_msg      db 'Memory patched', 13, 10, 7, 0
mbr_loaded_msg          db 'MBR loaded', 13, 10, 7, 0
jmp_to_mbr_msg          db 'Jumping to MBR code', 13, 10, 7, 0
disk_error_msg          db 'Disk error', 13, 10, 7, 0

_TEXT ENDS
END start
4

3 に答える 3

2

編集済み -- 新しい回答:

OK、最初にあなたの質問を誤解したようです。私ができる唯一のさらなるアドバイスはこれです:

  • HIMEM.SYSand/or EMM386.EXE(および他のメモリ マネージャー)をロードしていないことを確認します。ブートローダが実行されるとき、CPUはリアル モードでなければなりません。

  • Ralf Brown の割り込みリストを見てください。私の記憶が正しければ、ブート プロセスに関する技術情報がどこかにあるはずです。ヒントになるかもしれません。

  • 他のローダー ユーティリティのソース コードを見てくださいloadlin。(ユーティリティとまったく同じことを行うわけではありませんが、何らかの洞察が得られるかもしれません。)


以前の回答:

ブートローダーで行うのはORG 100h本当に正しいことですか?

.comDOS は最初の 256 バイトをプログラム セグメント プレフィックス (PSP) で初期化するため、これは DOS 実行可能ファイルにのみ関連すると思いました。ブートローダーを作成すると、DOS はなく、PSP などもありません。私はこれがなければならないと思いますORG 0

于 2010-04-14T17:43:12.000 に答える
2

私のDOSの知識は非常にさびており、答えをテスト/検証する時間がありませんでしたが、あなたの問題は次のとおりだと思います:

DOS またはその他の OS を起動すると、割り込みテーブルが変更されます。DOS は割り込みテーブルを変更するため、たとえば、割り込み 20 を使用してコマンドを DOS の「カーネル」に送信できます。これを行うには、元の割り込みハンドラーを保存し、それを独自のハンドラーに置き換えます。その後、デフォルトのフォールバックとして、割り込みの処理方法がわからない場合は元の割り込みハンドラーにチェーンします。このようにして、既存の BIOS 機能に新しい機能を「追加」し、DOS で実行されているすべてのプログラムは、いくつかのレジスタを設定してから割り込みを呼び出すだけで、システム コールを使用できます。

ただし、新しいオペレーティング システムを起動すると、この新しいオペレーティング システムは、a) すべての割り込みが BIOS によって処理され、b) その BIOS によって使用中であると報告されない限り、すべてのメモリが空きまたは未使用であると想定します。

そのため、新しい OS は古い OS で現在使用されているメモリを上書きし、ある時点で割り込みの 1 つを呼び出し、無効なメモリで何かを実行し、コンピュータがクラッシュします。

したがって、割り込みテーブルを元の BIOS バージョンにリセットすれば、問題ないはずです...

于 2010-10-31T23:14:47.333 に答える
0

これはブートローダーではないと思います。ブートセクターをロードして実行しようとするのは.comファイルです。したがって、DOSが初期化された後に実行されます。

于 2010-04-14T18:30:06.243 に答える