读了这么久,我真的很困惑。 据我读到:
现代操作系统根本不使用段。
GDT 用于定义内存中的段(包括约束)。
页表有一个管理位,指示当前位置是否用于内核。
维基百科表示“GDT 仍然存在于 64 位模式中;必须定义 GDT,但通常不会更改或用于分段。”
为什么我们需要它? linux 是如何使用它的?
最佳答案
- Modern OS does not use segments at all.
现代操作系统(针对 64 位 80x86)仍然使用段寄存器;只是它们的使用“大部分隐藏”在用户空间中(并且大多数用户空间代码可以忽略它们)。具体来说; CPU 将根据操作系统加载(从 GDT 或 LDT)到 CS
中的任何内容确定代码是否为 64 位(或 32 位或 16 位),中断仍会保存 CS
和 SS
用于中断的代码(并在 iret
处再次加载它们)、GS
和/或 FS
> 通常用于线程本地和/或 CPU 本地存储等。
- The GDT is used to define a segment in the memory (including constraints).
代码和数据段只是 GDT 的用途之一。另一个主要用途是定义任务状态段的位置(用于查找 IO 端口权限映射、当中断导致特权级别更改时加载到 CS、SS 和 RSP 中的值等)。 64 位代码(以及在 64 位内核下运行的 32 位代码/进程)仍然可以使用 GDT 中定义的调用门,但大多数操作系统不为 64 位代码使用该功能(他们使用syscall
来代替)。
- The page table has a supervisor bit that indicates if the current location is for the kernel.
是的。页表的管理位决定在 CPL=3 下运行的代码是否可以访问该页(或者代码是否必须在 CPL=2、CPL=1 或 CPL=0 下才能访问该页)。
- Wikipedia says that "The GDT is still present in 64-bit mode; a GDT must be defined but is generally never changed or used for segmentation."
是的 - 维基百科是正确的。通常,操作系统会在启动过程中尽早设置 GDT(对于 TSS、CS、SS 等),然后在启动后没有任何理由修改它;段寄存器不用于“分段内存保护”(但用于其他用途 - 确定代码大小、中断处理程序是否应返回 CPL=0 等)。
关于linux - 全局描述符表(GTD)的现代用法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64741681/