2

これは本当にばかげた質問ですが、私はそれを解決できないようです。私のOSでは、GDTは、カーネルとリンクアップされたアセンブリコードを介してセットアップされます。その場合、もちろん、GDTがロードされるときにデータセグメントとコードセグメントが設定されます。この情報は、アセンブリコードに次のように格納されます。

GDT_Contents db 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 154, 207, 0, 255, 255, 0, 0, 0, 146, 207, 0

すべてのセグメントが完全に設定されていますが、GDT_Contentsを指すポインターを介してGDTにアクセスできません。私はこれをいくつかの方法でテストしました。主に、0(GDT_Contentsの場所)へのポインターを作成し、それらのバイトをエコーアウトするだけです。それらはGDT_Contentsと一致しません。これは、GDTが読み込まれるときに、前のデータセグメント(0x0またはブートローダーによって設定されたもののいずれか)に関連しているためです。しかし、とにかく今はGDTにアクセスする方法がわかりません。TSSを設定したいのですが、TSS構造体へのポインターが必要なため、GDT_Contentsにハードコーディングすることはできません。以前のデータセグメントを復元するのと同じくらい簡単だと思いますが、どうすればそれができるのかわかりません。これは、GDTを設定するアセンブリコードです。

    cli
        mov dword [MultiBootInfo_Structure], EBX
        add dword EBX, 0x4
        mov dword EAX, [EBX]
        mov dword [MultiBootInfo_Memory_Low], EAX
        add dword EBX, 0x4
        mov dword EAX, [EBX]
        mov dword [MultiBootInfo_Memory_High], EAX
        mov dword ESP, Kernel_Stack
        mov dword [_NATIVE_GDT_Pointer + 2], _NATIVE_GDT_Contents
        mov dword EAX, _NATIVE_GDT_Pointer
        lgdt [EAX]
        mov dword EAX, 0x10
        mov word DS, EAX
        mov word ES, EAX
        mov word FS, EAX
        mov word GS, EAX
        mov word SS, EAX
        jmp 8:Boot_FlushCsGDT

Boot_FlushCsGDT:
        mov dword [_NATIVE_IDT_Pointer + 2], _NATIVE_IDT_Contents
        mov dword EAX, _NATIVE_IDT_Pointer
        lidt [EAX]
        mov dword EAX, CR4
        or dword EAX, 0x100
        mov dword CR4, EAX
        mov dword EAX, CR4
        or dword EAX, 0x200
        mov dword CR4, EAX
        mov dword EAX, CR0
        and dword EAX, 0xFFFFFFFD
        mov dword CR0, EAX
        mov dword EAX, CR0
        and dword EAX, 0x1
        mov dword CR0, EAX
        call __ENGINE_ENTRYPOINT__

    Boot_FlushCsGDT.loop:
        cli
        hlt
        jmp Boot_FlushCsGDT.loop
        ret 0x0

そしてもちろん、これは32ビット保護モードのx86です。

4

1 に答える 1

1

命令を使用してsgdt、GDTのサイズとアドレスを取得します。これは物理アドレスであるため、ページングを使用する場合は、アクセスする前に仮想メモリにマップされていることを確認する必要があります。sgdtGDT-1のサイズを指定されたアドレスの下位2バイトに格納し、物理アドレスを次の4バイトに格納します。

sgdt  dword [NewGDTPointer]

次に、GDTにTSS記述子用の空きスペースがすでにある場合は、そこに記述子を配置するだけです。それ以外の場合は、GDTをより大きなメモリにコピーして、新しいメモリをロードする必要があります。

于 2013-01-15T23:42:29.090 に答える