段寄存器如何参与内存地址转换?

Vor*_*Dev 0 hardware x86 x86-64 intel cpu-registers

在我迄今为止学到的关于分割的内容中:

  • 虚拟地址包含段选择器和偏移量
  • 段选择器与GDTR结合使用以查找段描述符的线性地址
  • 段描述符包含有关所选段的信息,包括其线性地址

所以,我的问题是:

  • 基于我所读到的内容,虚拟地址被加载到段寄存器中,然后以某种方式从那里继续转换.在将虚拟地址加载到其中以获取描述符后,段寄存器会发生什么?

  • 据我了解,段寄存器还包含描述符的缓存值.这在翻译过程中如何发挥作用?

  • 系统如何确定要加载哪个段寄存器,假设段选择器最多可以有2 ^ 13个不同的值且只有6个主寄存器?

Mar*_*oom 6

通常的翻译如下:

 Logical address   -->   GDT -->  Linear address          --> Page tables --> Physical Address
(segment:offset)                 (segment base + offset)         

\______________________________________________________/ 
                  Virtual address                                     
             (can be either logical or linear)
Run Code Online (Sandbox Code Playgroud)

如果在VMX非root模式下运行(即在VM中)并且启用了EPT,则:

 Logical address   -->   GDT -->  Linear address          --> Page tables --> Guest Physical Address --> EPT --> (System) Physical Address
(segment:offset)                 (segment base + offset)         

\______________________________________________________/                      \__________________________________________________________/
                  Virtual address                                                        Physical address
             (can be either logical or linear)
Run Code Online (Sandbox Code Playgroud)

如果存在IOMMU(如伞形技术VT-d):

Logical address   -->   GDT -->  Linear address          --> Page tables --> Guest Physical Address --> EPT --> (System) Physical Address  -->  1 or 2 level translation --> (IO) Physical address
(segment:offset)                 (segment base + offset)         

\______________________________________________________/                     \___________________________________________________________________________________________________________________/
                  Virtual address                                                        Physical address
             (can be either logical or linear)
Run Code Online (Sandbox Code Playgroud)

MMIO甚至可以执行访客虚拟地址或访客物理地址的转换(其中一个目的是将应用程序的虚拟地址重新定义到硬件并简化对翻译期间遇到的大量地址空间的管理).

注意正如Hadi Brais所指出的,术语"虚拟地址"仅在Intel和AMD手册中指定了一个线性地址.
我发现将逻辑和线性地址标记为虚拟更有用,因为它们在页面转换步骤之前.


段寄存器保存一个段选择该索引的片段的描述符,其用于执行安全检查,并获得该段被求和与的偏移部分的逻辑地址.
在那之后,它完成了.

在指令级指定的每个地址是逻辑地址 -规定的段的查找描述符.
为了避免每次通过指令访问内存时从内存中读取内存,CPU会对其进行缓存 - 否则这将成为性能杀手.

操作系统根据需要做的事情设置段寄存器,但无论如何它很少需要更多的四个段.

分段(在PM中)的主要目的是通过为每个程序定义非重叠段来实现过程隔离.
程序通常只需要一个堆栈段,数据段和代码段-其他三个在那里,以避免保存/恢复数据段回那么当段最大尺寸为64KiB(阅读:实模式.fsgs后来虽然加入).

今天操作系统使用平面模型,其中只有两个段(代码和数据/堆栈 - 这是一个简化,需要其他段)包含整个地址空间,以及TLS或PEB/TEB等操作系统特定段.
因此,六个段寄存器甚至超过了它所需要的,GDT的8192个条目就在那里,以防它们(如果需要).

  • 是的,英特尔优化手册使用术语虚拟地址作为线性地址的同义词。但我的观点是您的图片似乎表明虚拟地址是逻辑地址或线性地址。这有时是一些教科书和论文中使用的定义,但 Intel 和 AMD 不使用该定义。我认为图片应该反映现实中发生的情况,因为我认为您用 MMU 来指代 TLB 缓存。这就是为什么我说“GDT”应该被描述符缓存替换。这让我有点困惑。 (2认同)