問題タブ [gdt]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - ページングを有効にすると、トリプルフォールトが発生します(解決済み)
これが将来誰かを助ける場合:
- グローバル記述子テーブルが機能しているかどうかを確認します
- ページ テーブル エントリ構造体の要素が正しく並べられているかどうかを確認します
このコードは私のために働いた:
gdt.s
ページング.c
paging_asm.s
私の間違いは、構造体の下位ビットにアドレス フィールドがあり、上位ビットにフラグ フィールドがあることです。これが、いくつかの非常に奇妙な動作の原因でした。最終的にはmov cr0, eaxではなくmov esp, ebpでクラッシュしました。コメントしてくれたすべての人に感謝します。
segment - 「セグメント レジスタは、実アドレス モードと同じリニア アドレスを指し続けます」について説明を求めます。
問題は、Intel i386 でリアル モードからプロテクト モードに切り替える際のコード セグメント セレクターの永続的な有効性に関するものです。bootasm.S
切り替えコードは次のとおりです ( xv6 x86 バージョンからの抜粋)。
GDT レイアウトは次のとおりです。
行 9144 を実行した後、プロセッサは、単なるセグメント メモリ管理が有効になる保護モードに切り替わります (ただし、ページングはまだ有効になっていません)。私の理解では、セグメント MM が有効になっているため、後続の命令のフェッチはセグメント MM のルールに従う必要があります。ただし、この時点 (9153 行の直前) では、コード セレクターは 0 のままです。これは、コード セグメントが GDT の 0 番目の記述子 (null) を選択する必要があることを意味します。しかし、私の質問は自然に出てきます。そのようなヌル記述子が想定されるljmp
命令をどのようにロードできるのでしょうか? 私はグーグルで質問に答えようとしましたが、ドキュメントには次のような説明があります。
セグメント レジスタは、実アドレス モードと同じリニア アドレスを指し続けます。
この文は私の質問に答えているようです: セグメント レジスタが同じ線形アドレスを指し続ける場合、次の命令はリアル モードと同じ、つまりljmp
. しかし、すぐに一連の新しい質問があります。セグメント セレクターが「同じ線形アドレスを指し続ける」ことができるのはなぜですか? プロセッサがプロテクト モードに変更されていませんか? 0 の値は、命令%cs
をフェッチするための想定される記述子である 1 番目 (9184 行で設定) ではなく、0 番目の記述子を指していませんか? x86 CPUは、次の命令を実行する必要があることをljmp
魔法のようにどのように認識しますか? ljmp
この魔法を説明しているマニュアルの説明はどこにありますか? 私は、ljmp
はプロセッサの命令キューでプリフェッチされていますが、同じ Web ページの 2 番目の段落には、プリフェッチljmp
された が無効になっていることが示されているため、CPU は次の命令を新たにフェッチする必要があります。「セグメントレジスタがリアルアドレスモードと同じリニアアドレスを指し続ける」魔法のような方法を説明していただけますか? ありがとうございました。
PS、私が取り組んでいる CPU は Intel i386 互換です。