2

这是一个非常愚蠢的问题,但我似乎无法解决它。在我的操作系统中,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。

4

1 回答 1

1

使用该sgdt指令获取 GDT 的大小和地址。这是一个物理地址,因此如果您使用分页,则需要确保在访问它之前将其映射到虚拟内存。sgdt将 GDT-1 的大小存储在给定地址的低两个字节中,并将物理地址存储在接下来的四个中。

sgdt  dword [NewGDTPointer]

然后,如果 GDT 已经有 TSS 描述符的空白空间,您可以简单地将描述符放在那里。否则,您将需要将 GDT 复制到更大的内存并加载新的内存。

于 2013-01-15T23:42:29.090 回答