定义一个全局描述符Table有什么用?

What is the use of defining a Global Descriptor Table?

我阅读了有关 GDT(全局描述符 Table)的教程,该教程将 GDT 定义为“为内存的某些部分定义基本访问权限的工具”。这意味着GDT用于内存保护。

它是否执行上述任务以外的任何其他任务?

是否必须在操作系统中实现 GDT?

总之,如果有人能把GDT讲得通俗易懂一点就更好了。

谢谢

所有图片均取自Intel Manual 3A, §5.1
有关更多详细信息,OP 应阅读该手册,在这里我将仅公开一些为了简洁起见而简化的概念,以避免 link-only 答案。


顾名思义,全局描述符Table是一个描述符数组,可用于指定和定义系统范围的资源(因此 描述 这些资源)。

资源通常是连续内存区域,但也有其他类型的非常重要的资源。

描述符的分类是

Descriptors
    Non system descriptors

        Code segment descriptor
        Data segment descriptor
        Stack segment descriptor (Alias of the previous)

    System descriptors

        System segment descriptors

            LDT segment descriptor
            TSS segment descriptor

        Gate descriptors
            Call gate descriptor
            Interrupt gate descriptor
            Trap gate descriptor
            Task gate descriptor

除了 GDT 还有另一个 table, 描述资源的本地描述符 Table OS 仅适用于特定上下文。

描述符由其 table(GDTLDT)及其在 [=180 上的位置标识=],其 index

这样的索引被写入特定的寄存器,称为选择器寄存器(以前称为段寄存器)。
隐式或显式访问内存的每条指令都使用其中一个选择器。

xor eax, eax     ;eax is zero
xor esp, esp     ;esp is zero
xor ebx, ebx     ;ebx is zero

mov ecx, DWORD [eax]      ;Use DS selector (implicit)
mov ecx, DWORD [esp]      ;Use SS selector (implicit)
mov ecx, DWORD [fs:ebx]   ;Use FS selector (explicit)

所有这些指令读取逻辑地址 0,但CPU使用描述符计算新地址,称为线性地址 并执行安全检查。
所以这三个指令最终可能会读取完全不同的地址。

每个选择器还指定执行操作时应使用的权限。
cs 选择器很特殊,因为它不能再用 mov 改变(实际上已经有一段时间了),只能用分支指令(jmpretcall, ...).
它的用途不仅是在取代码时使用,它还拥有代码权限级别。
CPU 使用此权限级别来检查是否可以访问资源(使用请求的权限),检查并不总是微不足道的。

如您所见,每个描述符都有一个 DPL 字段来设置其特权级别。
所以它们是保护.

的一种形式

非系统描述符

非系统描述符用于定义旨在存储代码或数据及其属性的内存区域。

如您所见,这种描述符的目的是指定一块内存区域并为其附加一些属性。
特别是基地址,限制(大小),访问它所需的权限(DPL字段,检查实际上比这个更复杂),代码的大小(仅代码), 如果允许 read/write 等等。

长模式(64 位)改变了属性的解释方式,请注意。

系统描述符

OS 使用系统描述符来控制用户模式程序。

系统段描述符

这些描述符定义了用于存储LDT和另一个名为Task State Segment的结构的内存区域(英特尔提供的一种机制,用于缓和任务切换)。
系统中可以有不止一个这样的结构,被选中的结构由ldtr(LDT寄存器)和tsr(TS寄存器)指示) 寄存器。

门描述符

这些用于将控制转移到其他(或多或少特权)代码。

呼叫门

如果您查看图片,您会发现 调用门 本质上是一个元描述符,它指定了一个选择器和该描述符指定区域的偏移量以及特权。
它用于将控制权传递给特权例程。

call fs:0badbabeh

假设fs持有门的索引,CPU根本不会使用直接地址0badbabeh,而是使用关于大门本身。

中断和陷阱门

与中断一起使用,两者的区别在于前者清除if标志,后者不清除。

它们与调用门非常相似。

这些描述符实际上是放在另一个table,通常是中断描述符Table
另一个 table 没有用选择器索引,而是用中断号索引。
如果我没记错的话,它们也可以放在 GDT/LDT 中,像其他门一样使用。

一个任务门可用于执行任务切换。

任务门

这些类似于调用门,但将控制转移到新任务(任务切换)。

一些重新sources不是简单的内存区域,可以是gates

让我给你两个问题的答案:

答案 #1:在 64 位 Intel 中,全局描述符 Table 没有任何用处。

答案 #2:在 16 位 Intel 中,全局描述符 Table 包含系统上所有进程共享的对象的描述符。本地描述符 Tables 对单个进程使用的描述符进行相同的操作。可以有多个 LDT(每个进程一个),但所有进程只能共享一个 GDT(尽管理论上可以为不同的进程更改 GDT)。

在 32 位英特尔中,运行 32 位系统中的遗留 16 位代码需要 GDT 和 LDT。

除非您需要处理 16 位应用程序,否则学习 GDT 和 LDT 与学习如何操作打卡机一样有用。