x86架构 分页内存管理 虚拟内存管理 全局描述符表

80386 将逻辑地址(程序员眼中的地址)翻译为物理地址(向内存发送的地址)的两个步骤:

  1. 段翻译:将一个逻辑地址(由段寄存器和偏移寄存器组成)翻译为一个线性地址。
  2. 页翻译:将一个线性地址翻译为一个物理地址。这一步是可选的,当页表还没建立的时候,线性地址直接作为物理地址。

1 段翻译

为了完成段翻译,CPU 使用以下数据结构:

  • 描述符(Descriptors)
  • 描述符表(Descriptors table)
  • 选择器(Selectors)
  • 段寄存器(Segment Registers)

1.1 描性述符

段描述符为处理器提供将逻辑地址映射到线性地址所需的数据。描述符由编译器、链接器、加载器或操作系统创建,而不是由应用程序程序员创建。段描述符字段是:

  • BASE:定义段在 4 GB 线性地址空间内的位置。处理器将三个段值和基地址组成单个 32 位值。
  • LIMIT:定义段的大小。当处理器连接限制字段的两个部分时,会产生一个 20 位的值。处理器以两种方式之一解释限制字段,具体取决于粒度位的设置。
  • 粒度位(Granularity bit):指定解释 LIMIT 字段的单位。当该位清零时,限制以一字节为单位进行解释;设置后,限制以 4 KB 为单位进行解释。
  • TYPE:区分各种描述符。
  • DPL(Descriptor Privilege Level):保护级别
  • Segment-Present 位:如果该位为零,则描述符不能用于地址转换;当描述符的选择器加载到段寄存器中时,处理器将发出异常信号。
  • 访问位:处理器在访问段时设置该位;

描述符的创建和维护是系统软件的责任,通常需要编译器、程序加载器或系统构建器以及评价系统的合作。

截屏2021-08-18 下午10.23.01

描述符表只是一个包含描述符的 8 字节条目的存储器阵列,如图 5-5所示。描述符表的长度可变,最多可包含 8192 (2^(13)) 个描述符选择器有16位,如下图所示,选择器为16位,索引号13位,TI(指示从GDT还是LDT中找)、请求特权级(RPL)。但是,处理器不使用 GDT 的第一个条目 (INDEX=0)。
截屏2021-08-18 下午10.58.24
截屏2021-08-18 下午10.57.12

1.2 Descriptor Tables

段描述符存储在两种描述符表中的任一种中:

  • 全局描述符表 (GDT)
  • 本地描述符表 (LDT)

处理器通过 GDTR 和 LDTR 寄存器在内存中定位 GDT 和当前 LDT。这些寄存器存储表的大小和地址。LGDT(加载全局描述符表),SGDT(存储全局描述符表),LLDT(加载本地描述符表),SLDT(存储局部描述符表)。

1.3 选择器(Selectors)

逻辑地址的选择器部分通过指定一个描述符表并在该表中索引一个描述符来标识一个描述符。选择器可能作为指针变量中的一个字段对应用程序可见,但选择器的值通常由链接器或链接加载器分配(固定)。

截屏2021-08-18 下午11.30.26

索引(index):选择描述符表中的 8192 个描述符之一。处理器简单地将该索引值乘以 8(描述符的长度),并将结果与描述符表的基地址相加,以便访问表中适当的段描述符。

表指示符(Table Indicator):指定选择器引用哪个描述符表。零表示 GDT;一表示当前的 LDT。

请求的特权级别(Requested Privilege Level):由保护机制使用

由于处理器不使用 GDT 的第一个条目,因此索引为零且表指示符为零的选择器(即指向 GDT 的第一个条目的选择器)可以用作空值选择器。当段寄存器(除了 CS 或 SS)加载了空选择器时,处理器不会导致异常。但是,当使用段寄存器访问内存时,它会导致异常。此功能对于初始化未使用的段寄存器以捕获意外引用很有用。

1.4 段寄存器

80386 将来自描述符的信息存储在段寄存器中,从而避免每次访问内存时都需要查阅描述符表。

每个段寄存器都有一个“可见”部分和一个“不可见”部分, 如图 5-7所示。这些段地址寄存器的可见部分由程序操作,就好像它们只是 16 位寄存器一样。不可见部分由处理器操纵。加载这些寄存器的操作是正常的程序指令。这些指令分为两类:

  1. 直接加载指令;例如,MOVPOPLDSLSSLGSLFS。这些指令明确引用段寄存器。
  2. 隐含负载指令;例如, far CALLJMP。这些指令隐式引用 CS 寄存器,并用新值加载它。
截屏2021-08-18 下午11.39.48

使用这些指令,程序加载带有 16 位选择器的段寄存器的可见部分。处理器自动从描述符表中获取基地址、限制、类型和其他信息,并将它们加载到段寄存器的不可见部分。

由于大多数指令引用的段中的数据的选择器已加载到段寄存器中,因此处理器可以将指令提供的段相对偏移量添加到段基地址,而无需额外开销。

2 页面翻译

在地址转换的第二阶段,80386 将线性地址转换为物理地址。地址转换的这个阶段实现了面向页面的虚拟内存系统和页面级保护所需的基本功能。

页面翻译步骤是可选的。页转换仅在 CR0 的 PG 位被设置时才有效。该位通常由操作系统在软件初始化期间设置。如果操作系统要实现多个虚拟 8086 任务、面向页面的保护或面向页面的虚拟内存,则必须设置 PG 位。

2.1 页框

页框是一个 4K 字节的物理内存连续地址单元。页从字节边界开始,大小固定。

2.2 线性地址

线性地址通过指定页表、该表内的页和该页内的偏移量间接引用物理地址。 线性地址的格式如图 5-8所示。

截屏2021-08-18 下午11.47.29

图 5-9 显示了处理器如何通过查询两级页表将线性地址的 DIR、PAGE 和 OFFSET 字段转换为物理地址。寻址机制使用 DIR 字段作为页目录的索引,使用 PAGE 字段作为页目录确定的页表的索引,并使用 OFFSET 字段对页表确定的页内的字节进行寻址。

截屏2021-08-18 下午11.53.25

2.3 页表

页表只是一个 32 位页说明符的数组。页表本身就是一个页,因此包含 4 KB 内存或最多 1K 32 位条目。两级表用于寻址一页内存。在更高级别是页面目录。页目录最多可寻址 1K 个第二级页表。第二级页表最多可寻址 1K 页。因此,由一个页目录寻址的所有表可以寻址 1M 页 (2^(20))。因为每页包含 4K 字节(2^(12) 字节),一个页目录的表可以跨越 80386 的整个物理地址空间(2^(20) 乘以 2^(12) = 2^(32))。

当前页目录的物理地址存储在 CPU 寄存器 CR3 中,也称为页目录基址寄存器(PDBR)。内存管理软件可以选择为所有任务使用一个页面目录,为每个任务使用一个页面目录,或者两者的某种组合。 有关 CR3 初始化的信息,请参阅 第 10 章。请参阅 第 7 章 以了解 CR3 如何针对每个任务进行更改。

2.4 页表条目

任一级别页表中的条目具有相同的格式。 图 5-10 说明了这种格式。

截屏2021-08-19 上午12.01.41
2.4.1 物理页地址(Page Frame Address)

页框地址(物理页地址)指定页面的物理起始地址,由于页面位于 4K 边界上,因此低 12 位始终为零。在页目录(page directory)中,页框地址就是页表(page table)的地址。在二级页表中,页框地址是包含所需内存操作数的页框地址。

2.4.2 当前位(Present Bit)

当任一层页表中P=0时,该条目对地址转换无效,其余条目可供软件使用;条目中的其他位均未经过硬件测试。 图 5-11说明了 P=0 时页表条目的格式。截屏2021-08-19 上午11.48.08

如果尝试使用页表条目进行地址转换时,任一级别页表中的 P=0,则处理器发出页异常信号。在支持分页虚拟内存的软件系统中,页面不存在异常处理程序可以将所需的页面带入物理内存。然后可以重新执行导致异常的指令。

请注意,页目录本身没有存在位。当相关任务挂起时,页目录可能不存在,但操作系统必须确保在任务被分派之前,TSS 中 CR3 映像指示的页目录存在于物理内存中。

2.4.3 访问位和脏位(Accessed and Dirty Bits)

这些位提供有关页表两个级别中的页使用情况的数据。除了页目录项中的脏位外,这些位由硬件设置;但是,处理器不会清除这些位中的任何一位。

在写入该页表条目所覆盖的地址之前,处理器将第二级页表中的脏位设置为 1。目录条目中的脏位未定义。

当内存需求超过可用物理内存时,支持分页虚拟内存的操作系统可以使用这些位来确定从物理内存中删除哪些页面。操作系统负责测试和清除这些位。

2.4.4 读/写和用户/管理员位 (Read/Write and User/Supervisor Bits)

这些为不用于地址转换,而用于不同级别的保护。CPU 在地址转换的同时判断。

2.5 页面转换缓存(Page Translation Cache)

为了实现地址转换的最大效率,处理器将最近使用的页表数据存储在片上缓存中。只有当必要的分页信息不在缓存中时,才必须引用两级页表。

页翻译缓存的存在对应用程序程序员是不可见的,但对系统程序员是不可见的;每当页表发生变化时,操作系统程序员都必须刷新缓存。可以通过以下两种方法之一刷新页面转换缓存:

  • 通过使用MOV 指令来重新载入 CR3

    MOV CR3, EAX
    
  • 执行任务切换到与当前 TSS 具有不同 CR3 镜像的 TSS。

3 结合 段和页 翻译

图 5-12 总结了当页表可用时,一个逻辑地址到物理地址的转换过程。通过对各个阶段进行合理选择和参数配置,内存管理系统能实现多个不同风格的内存管理系统。

3.1 “扁平化”架构

当 80386 用于执行为没有分段的架构设计的软件时,有效地“关闭”80386 的分段功能可能是有利的。80386 没有禁用分段的模式,但效果相同可以通过最初将包含整个 32 位线性地址空间的描述符的选择器加载到段寄存器来实现。加载后,不需要更改段寄存器。80386 指令使用的 32 位偏移量足以寻址整个线性地址空间。相当于将整整 32位 地址空间作为一个大段来使用。

80386 的架构允许段大于或小于页面大小(4 KB)。例如,假设一个段用于寻址和保护跨越 132 KB 的大型数据结构。在支持分页虚拟内存的软件系统中,整个结构不必一次位于物理内存中。该结构分为 33 页,其中可能不存在任意数量的页。应用程序程序员不需要知道虚拟内存子系统正在以这种方式对结构进行分页。

3.3 跨多个段的页面

另一方面,段可能小于页面的大小。例如,考虑一个小的数据结构,如信号量。由于段提供了保护和共享,为每个信号量创建一个单独的段可能很有用。但是,因为一个系统可能需要许多信号量,为每个信号量分配一个页面效率不高。因此,在页面内聚集许多相关段可能很有用。

3.4 未对齐的页面和段边界

80386 的体系结构不强制页面和段边界之间的任何对应关系。一个页面包含一个段的结尾和另一个段的开头是完全允许的。同样,一个段可能包含一页的结尾和另一页的开头。

3.5 对齐的页面和段边界

然而,如果内存管理软件强制页面和段边界之间的某种对应关系,它可能会更简单。例如,如果段仅以一页为单位进行分配,则可以将段和页分配的逻辑结合起来。不需要逻辑来解释部分使用的页面。

3.6 每段一个页表

一种进一步简化空间管理软件的空间管理方法是维护段描述符和页目录条目之间的一对一对应关系, 如图 5-13所示。每个描述符都有一个基地址,其中低 22 位为零;换句话说,基地址由页表的第一个条目映射。一个段可以有 1 到 4 兆字节的任何限制。根据限制,该段包含在 1 到 1K 页帧中。因此,一个任务被限制为 1K 段(对于许多应用程序来说已经足够了),每个段最多包含 4 MB。描述符、相应的页目录条目和相应的页表可以同时分配和释放。

截屏2021-08-19 下午12.28.06
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值