简体   繁体   English

设置数据段后是否访问GDT?

[英]Access GDT after data segment had been set?

This is a really stupid question, but I can't seem to solve it. 这是一个非常愚蠢的问题,但我似乎无法解决。 In my OS the GDT is setup via assembly code that links upped with the kernel. 在我的操作系统中,GDT是通过汇编代码设置的,该汇编代码链接了内核。 When that happens, of course the data segment and code segment are set up when the GDT is loaded. 发生这种情况时,当然会在加载GDT时设置数据段和代码段。 The this information is stored in the assembly code as 此信息存储在汇编代码中,格式为

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

All the segments are set up perfectly, however I can not access the GDT via a pointer that points to GDT_Contents. 所有段均设置完善,但是我无法通过指向GDT_Contents的指针访问GDT。 I have tested this several ways, mainly by just creating a pointer to 0 (That is the location of GDT_Contents) and echoing out the bytes that are their. 我已经测试了这几种方法,主要是通过仅创建一个指向0的指针(即GDT_Contents的位置)并回显它们的字节。 They do not match up with the GDT_Contents. 它们与GDT_Contents不匹配。 I am pretty sure this is because when the GDT gets loaded it is relative to the prior data segment (either 0x0 or set up by the bootloader, I am not sure). 我非常确定这是因为加载GDT时,它是相对于先前的数据段(0x0还是由引导程序设置的,我不确定)。 But anyways I do not know how I can access the GDT now, I want to set up the TSS I can't just hardcode that into GDT_Contents since it requires a pointer to my TSS Struct. 但是无论如何,我现在不知道如何访问GDT,我想设置TSS,我不能只是将其硬编码到GDT_Contents中,因为它需要一个指向我的TSS结构的指针。 I think it is just as easy as restoring the previous data segment, but I have no idea how I can do that. 我认为这与恢复上一个数据段一样容易,但是我不知道如何做到这一点。 This is the assembly code that sets up the GDT 这是设置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

And of course this is x86 in 32 bit protected mode. 当然,这是32位保护模式下的x86。

Use the sgdt instruction to get the size and address of the GDT. 使用sgdt指令获取GDT的大小和地址。 This is a physical address, so if you use paging you will need to ensure it is mapped into virtual memory before you access it. 这是一个物理地址,因此,如果您使用分页,则需要确保在访问前将其映射到虚拟内存中。 sgdt stores the size of the GDT-1 in the low two bytes at the address given, and the physical address in the next four. sgdt将GDT-1的大小存储在给定地址的低两个字节中,并将物理地址存储在下四个字节中。

sgdt  dword [NewGDTPointer]

Then, if the GDT has empty space for the TSS descriptor already, you can simply place the descriptor there. 然后,如果GDT已经为TSS描述符保留了空白,则只需将描述符放在此处即可。 Otherwise, you will need to copy the GDT to a larger piece of memory and load the new one. 否则,您将需要将GDT复制到更大的内存中并加载新的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM