这真是个愚蠢的问题,但我似乎解决不了在我的操作系统中,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_内容的指针访问GDT我已经测试了几种方法,主要是创建一个指向0的指针(即GDT_内容的位置)并回显它们的字节它们与GDT_的内容不匹配我很确定这是因为当GDT被加载时,它是相对于先前的数据段的(0x0或由引导加载程序设置,我不确定)但无论如何,我现在不知道如何访问GDT,我想设置TSS我不能硬编码成GDT_内容,因为它需要指向我的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。
最佳答案
使用sgdt
指令获取GDT的大小和地址这是一个物理地址,因此如果使用分页,则需要确保在访问之前将其映射到虚拟内存中sgdt
将GDT-1的大小存储在给定地址的低位两个字节中,物理地址存储在接下来的四个字节中。
sgdt dword [NewGDTPointer]
然后,如果GDT已经为TSS描述符留有空空间,那么只需将描述符放在那里否则,您需要将GDT复制到更大的内存中并加载新的内存。
关于c - 设置数据段后是否访问GDT?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14290372/