首页 > 解决方案 > 全局描述符表(GTD)的现代用法是什么?

问题描述

读了很久,真的很迷茫。从我读到的:

  1. 现代操作系统根本不使用段。

  2. GDT 用于在内存中定义一个段(包括约束)。

  3. 页表有一个主管位,指示当前位置是否用于内核。

  4. 维基百科说“GDT 仍然存在于 64 位模式;必须定义 GDT,但通常永远不会更改或用于分段。”

为什么我们需要它?以及linux如何使用它?

标签: linuxoperating-systemgdt

解决方案


  1. 现代操作系统根本不使用段。

现代操作系统(用于 64 位 80x86)仍然使用段寄存器;只是它们的使用对用户空间“大部分是隐藏的”(并且大多数用户空间代码可以忽略它们)。具体来说; CPU 将确定代码是 64 位(或 32 位还是 16 位),无论操作系统加载(从 GDT 或 LDT)到什么CS,中断仍然保存CSSS为被中断的代码(并再次加载它们iret),GS和/或FS通常用于线程本地和/或 CPU 本地存储等。

  1. GDT 用于在内存中定义一个段(包括约束)。

代码和数据段只是 GDT 的用途之一。另一个主要用途是定义任务状态段的位置(用于查找 IO 端口权限映射,当中断导致特权级别更改时加载到 CS、SS 和 RSP 中的值等)。64 位代码(以及在 64 位内核下运行的 32 位代码/进程)仍然可以使用 GDT 中定义的调用门,但大多数操作系统不会将该功能用于 64 位代码(他们syscall改为使用)。

  1. 页表有一个主管位,指示当前位置是否用于内核。

是的。页表的主管位确定在 CPL=3 下运行的代码是否可以/不能访问该页(或者代码是否必须为 CPL=2、CPL=1 或 CPL=0 才能访问该页)。

  1. 维基百科说“GDT 仍然存在于 64 位模式;必须定义 GDT,但通常永远不会更改或用于分段。”

是的——维基百科是对的。通常,操作系统会在启动的早期设置 GDT(用于 TSS、CS、SS 等),然后在启动后没有任何理由修改它;并且段寄存器不用于“分段内存保护”(但用于其他事情 - 确定代码大小,中断处理程序是否应返回 CPL=0 等)。


推荐阅读