我正在开发一个小型操作系统,它将为每个进程使用单独的本地描述符表。我知道我需要使用该lldt
指令从我的 GDT 加载 LDT 段。我的内核已经使用有效的 GDT 在保护模式下运行,但我无法弄清楚我的 LDT 的 GDT 条目应该是什么样子。我知道它的基地址应该指向我的LDT,但我不知道特权级别和其他属性应该是什么。这是代表我的 GDT 中的 LDT 条目的 NASM 代码:
localTable equ $-gdt ; GDT entry #5 (selector 20h)
dw 0x1FF ; limit to 64 descriptors
dw 0x8000 ; base address
db 0x0
db 0x89 ; probably incorrect...
db 0x1f ; possibly incorrect...
db 0x0
如果您不熟悉 NASM 语法,则此表条目的基地址为 0x8000,限制为 511(总共 512 个字节,或 64 个条目)。我已经阅读了 i486 程序员参考手册中关于 GDT 和 LDT 的部分,但我无法完全理解我的 GDT 条目应该是什么样子。
无论如何,我像这样加载 LDT:
mov ax, 0x20
lldt ax
此代码导致处理器产生一般保护故障(我用中断处理它)。我想知道两件事:
1) 我是否在 GDT 中正确描述了我的 LDT?如果不是,需要改变什么?2)LLDT
指令是否会因为我的 LDT 本身存在无效的选择器而失败?我阅读了 LLDT 指令规范,在我看来它甚至没有读取 LDT 的内存,但我只是想确保 LLDT 没有失败,因为我的 LDT 数据中有错字。