数据段设置后访问GDT?

时间:2013-01-12 04:55:49

标签: c assembly x86 gdt memory-segmentation

这是一个非常愚蠢的问题,但我似乎无法解决它。在我的操作系统中,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 Struct的指针。我认为它就像恢复以前的数据段一样简单,但我不知道如何做到这一点。这是设置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。

1 个答案:

答案 0 :(得分:1)

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

sgdt  dword [NewGDTPointer]

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