这是一个非常愚蠢的问题,但我似乎无法解决它。在我的操作系统中,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,我不能将其硬编码到 GDT_Contents 中,因为它需要指向我的 TSS 结构的指针。我认为这就像恢复以前的数据段一样容易,但我不知道该怎么做。这是设置 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。