9

我一直在阅读有关虚拟内存(分段+分页)的英特尔手册。据我了解,有一个保存全局描述符表(GDT)的特殊寄存器。GDT 包含 NULL 描述符、本地描述符表、TSS 和段描述符。此外,几乎所有操作系统 (OS) 都有一个 GDT,并且在引导时加载并且无法更改(也许!!!)。我的问题是:

  1. 所有这些信息(NULL、LDT、TSS 和段描述符)存储在哪里?它们在物理内存、RAM 还是本地硬盘中?
  2. 段描述符是否与代码段 (ASM: CS)、数据段 (ASM: DS) 相同,如果是,则其中有多少存储在 GDT 中(是否只有一个 CS,一个 DS,...) ?
  3. Protable Executable (PE) Loader 是否操纵这些信息?
4

3 回答 3

14

所有这些信息(NULL、LDT、TSS 和段描述符)存储在哪里?它们在物理内存、RAM 还是本地硬盘中?

如果 CPU 没有在内部缓存 GDT 的内容,那么它可能需要时不时地访问它,也许一直都需要。CPU 不能直接从磁盘读取它,因为它不知道磁盘或上面的文件系统的任何信息,也不知道如何不干扰访问同一磁盘的操作系统。CPU 也不能依赖 OS 的帮助,因为 OS 在从磁盘获取某些东西的过程中,也可以让 CPU 从 GDT 获取一些东西。捕获 22。

您真的不希望将 GDT 换出到磁盘。如果不是因为上述原因,那么是因为性能影响。所以 GDT 总是在内存中,物理内存(=RAM)。

段描述符与代码段 (ASM: CS)、数据段 (ASM: DS) 是否相同,如果是,则其中有多少存储在 GDT 中(是否只有一个 CS,一个 DS,...) ?

段寄存器(CS、DS 等)包含段选择器,它们基本上是保护模式下 GDT(或 LDT)的索引,这些索引指向/选择描述符表中的段描述符。在真实和虚拟 8086 模式中它是相同的,除了不使用表,因为段位置和大小(我们从保护模式下的表中获得)不是任意的并且不需要查找,它们是立即计算的。

请注意,以下术语的含义不同,请勿混淆或互换使用:

  • 段寄存器
  • 段选择器
  • 段描述符
  • 段描述符表
  • 部分

Protable Executable (PE) Loader 是否操纵这些信息?

它不应该。至少不是直接的。大多数 Windows 程序在 CS、DS、ES、SS 中使用相同的段选择器值。这些选择器指向的 GDT 条目不会改变,它们是全局的并且在所有程序之间共享。

程序和线程之间通常唯一不同的是用于访问线程本地存储(TLS)的段(可能还有它的选择器)。FS 或 GS​​ 段寄存器保存指向该 TLS 段的选择器。并且所有对 TLS 的访问都是通过使用适当的段覆盖前缀(FS: 或 GS​​:)的指令完成的。TLS 对于每个线程都是唯一的。

于 2012-10-04T00:09:00.500 回答
7

OSDev.org 对 GDT 进行了很好的介绍,然而,详细介绍其实现的教程更有趣。(您可能还对其较小、特权较低的表亲LDT感兴趣)

  1. GDT 驻留在主内存中,并使用线性地址(通过LGDT)加载,因此它可能位于分页内存中。

  2. 是的(请参阅词汇表),您可以存储您喜欢的任何段基础,通常,CS 和 DS 是最低限度的(如果使用SYSENTER/则需要用户+内核版本SYSEXIT)。

  3. 不,它宁愿改变 LDT(因为 x86 提供了交换它们的工具,而不是 GDT,它需要设置实模式指令,并且在实模式和保护模式之间跳转是不可行的)。

于 2012-10-03T20:28:36.027 回答
1

我同意上面的答案,但是对于问题 2 的更完整的答案是:
段描述符指定段的大小、段的访问权限和特权级别、段类型以及第一个字节的位置线性地址空间中的段(称为段的基地址)。所以段描述符不仅仅是 CS、DS、... 寄存器。

于 2016-07-04T13:14:45.623 回答