2
votes

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. When that happens, of course the data segment and code segment are set up when the GDT is loaded. 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. 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. They do not match up with the 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). 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. 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

    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.

1

1 Answers

1
votes

Use the sgdt instruction to get the size and address of the 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  dword [NewGDTPointer]

Then, if the GDT has empty space for the TSS descriptor already, you can simply place the descriptor there. Otherwise, you will need to copy the GDT to a larger piece of memory and load the new one.