是否有关于如何布置全局描述符表条目的约定?

问题描述

操作系统是否有约定的约定,指定每个表索引应描述的内容?例如,在 Windows 系统上(如 here 所述),条目 4 描述 32 位用户模式代码RPL = 3),条目 6 描述 64 位用户模式代码。这是公约吗?其他条目呢?

解决方法

x86-64 syscall/sysret 和 32 位 sysenter/sysexit,显然确实关心 GDT 的顺序条目:内核 CS、内核数据、用户 CS、用户数据。 (感谢@Brendan 提供的详细信息。)或者至少,syscall 将固定值加载到 CS 和 SS 内部状态:

SYSCALL 使用源自 IA32_STAR MSR 的位 47:32 的值加载 CS 和 SS 选择器。但是,CS 和 SS 描述符缓存不是从这些选择器引用的描述符(在 GDT 或 LDT 中)加载的。相反,描述符缓存加载有固定值。有关详细信息,请参阅操作部分。操作系统软件有责任确保这些选择器值引用的描述符(在 GDT 或 LDT 中)与加载到描述符缓存中的固定值相对应; SYSCALL 指令不能确保这种对应关系。

除此之外,硬件无关紧要;如果您只使用像 int 0x80 这样的传统系统调用机制,任何对您有意义的模式都可以。
AFAIK,跨操作系统没有标准约定,但这不是我看过的东西。


当内核设置条目时(例如在上下文切换时),条目可能通过缓存获取,因此将一起使用的条目放在同一个 64 字节缓存行中可能会有一个微小的优势。 (减少缓存未命中/占用的缓存行数。)特别是对于 32 位用户空间,如果您不能为其 SS/DS/ES 仅使用空选择器 (0)。

但如果整个 GDT 是 8 个条目或更少,则整个内容适合一个缓存行(如果您将开头对齐 64)。较旧的 CPU(在 Pentium 4 / Core 2 之前)具有 32 字节缓存线,但它们不支持 64 位模式,因此需要的 GDT 条目较少。

请注意,索引 0 永远不会被 CPU 实际访问,因此您可以将第一个“真实”GDT 条目和 lgdt 与该地址减去 8 对齐。(“空描述符”是一种特殊情况.)