これは本当にばかげた質問ですが、私はそれを解決できないようです。私の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です。