2

カスタム カーネル用のブートローダーを作成しています。これ (ブートローダー) は Linux カーネル v0.1 に基づいていますboot.s。コードは次のとおりです。

.set    BOOTSEG, 0x7c0
.set    LOADSEG, 0x9000
.set    SYSSEG, 0x1000

start:
//copy the WHOLE bootloader to new location
movw    BOOTSEG, %ax
movw    %ax, %ds
xor     %si, %si
movw    LOADSEG, %ax
movw    %ax, %es
xor     %di, %di
movw    256, %cx
rep     movsw

//jump to new location
cli
movw    LOADSEG, %ax
movw    %ax, %es
ljmp    $LOADSEG, $loaded

loaded:
// ...

movw  $0x3, %ax
int   $0x10

// ...

新しい場所にジャンプしようとすると、Bochs は次のように書き込みます:が、私のコードWARNING: HLT instrucion with IF=0にはまったくhlt指示がありません。ジャンプ後、Bochs は実行を続けますが、正しく動作しません。たとえばint $0x10、画面がクリアされません。

ブートローダを間違ってコピーしたのかもしれませんが、Linux に似ています。

それで、誰でもこの問題を手伝ってもらえますか?

4

1 に答える 1

3

Bochs は、あなたの IF (割り込みフラグ、割り込み許可) が 0 であると言っているので、問題はあなたの遠いジャンプにあるに違いありません。次のことを確認する必要があります。

  1. ラベルの後のコードには指示loadedが含まれていませんhlt
  2. ラベルの正しいオフセットがありますloaded(使用するコンパイラまたはリンカーの設定を確認してください)

osdev の投稿によると、GDT のセグメント セレクターをセグメント レジスタに関連付けようとしています。リアル モードで実行する場合、セグメント レジスタの値は GDT エントリの取得に使用されませんが、シフトされ、標準のリアル モード セグメントとしてオフセットに追加されます。セグメントを GDT エントリに設定するコードをコメントアウト (または削除) すると、すべてが機能するはずです。それを試してみてください。

それが機能する理由は単純です。CS セグメントを からLOADSEGに変更すると0x8、実際にリアル モードの IVT 空間に移動します。

GDT を使用する場合は、最初に保護モードにジャンプする必要があります。このトピックの詳細については、Brokenthorn.comのよく書かれたチュートリアルを参照してください。

于 2013-08-16T12:36:51.057 に答える