5

物理メモリの場所に直接書き込もうとしているので、アセンブリ関数を使用して最初にページングを無効にし、値を書き込んでから再度ページングを有効にしていますが、なんらかの理由で、価値。

私が理解しているように、x86-32bit では、cr0 のビット 32 を反転することでページングのオンとオフが設定されるため、ここに私のアセンブリ関数を示します。

mov 4(%esp), %ecx //address
mov 8(%esp), %edx //value

mov %cr0, %eax
and $0x7fffffff, %eax
mov %eax, %cr0

mov %edx, (%ecx) //this line still triggers a page fault somehow

or $0x80000000, %eax
mov %eax, %cr0

ret

これは私がやりたいことを達成する正しい方法ですか? その場合、cr0 のビットが反転した状態でページ フォールトが引き続きトリガーされるのはなぜですか?

4

2 に答える 2

3

Intel 64 and IA-32 Architectures Software Developer's Manual System Programming Guideでは、プロテクト モードからリアル モードに切り替える手順の一部として、ページングを無効にする方法について説明しています。

9.9.2 実アドレスモードへの切り替え

ソフトウェアが MOV CR0 命令で CR0 レジスタの PE ビットをクリアすると、プロセッサは保護モードから実アドレス モードに切り替わります。実アドレス モードに再び入る手順では、次の手順を実行する必要があります。

  1. 割り込みを無効にします。CLI 命令は、マスカブル ハードウェア割り込みを無効にします。NMI 割り込みは、外部回路で無効にすることができます。
  2. ページングが有効になっている場合は、次の操作を実行します。

    • プログラム制御を、物理アドレスに ID マップされた線形アドレスに転送します (つまり、線形アドレスは物理アドレスと同じです)。
    • GDT と IDT が ID マップ ページにあることを確認します。
    • CR0 レジスタの PG ビットをクリアします。
    • CR3 レジスタに 0H を移動して、TLB をフラッシュします。

最後のステップを逃したようです。TLB (変換ルックアサイド バッファ) は、CPU がページ テーブル エントリをキャッシュし、PG ビットをクリアした後もアクティブな場所です。TLB をクリアする必要があります。クリアしないと、CPU が使用し続けます。

PG ビットを再度設定する前に、CR3 をリロードする必要があることに注意してください。また、実行していることは非常に珍しいため、エミュレーターでバグや互換性の問題が発生する可能性があります。ページングの無効化を正しく処理できるのは、リアル モードに戻すプロセスの一部としてのみである可能性があります。これは、テストされた唯一のシナリオである可能性が高いためです。物理 CPU でも、この領域で問題が発生する場合があります。

于 2015-11-23T19:28:03.983 に答える