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

时间:2018-09-07 12:00:21

标签: x86 x86-64 hardware intel cpu-registers

到目前为止,我对细分的了解是

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

所以,我的问题是:

  • 根据我所读的内容,将虚拟地址加载到段寄存器中,然后以某种方式从那里继续翻译。在将虚拟地址加载到段寄存器以获得描述符之后,段寄存器会发生什么?

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

  • 鉴于段选择器最多可以具有2 ^ 13个不同的值并且只有六个主寄存器,系统如何确定要加载到哪个段寄存器?

1 个答案:

答案 0 :(得分:6)

通常的翻译如下:

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

\______________________________________________________/ 
                  Virtual address                                     
             (can be either logical or linear)

如果以VMX非根模式(即在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)

如果存在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)

MMIO甚至可以执行来宾虚拟地址或来宾物理地址的转换(目的之一是将应用程序的虚拟地址验证为硬件,并简化管理过程中遇到的过多地址空间的管理)翻译)。

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


段寄存器包含一个段选择器,该段索引一个段描述符,该段用于执行安全检查并获取段 base 逻辑地址的偏移量部分相加。
之后,就完成了。

在指令级别指定的每个地址都是逻辑地址-需要查找段 descriptor
为了避免每次通过指令访问内存时从内存中读取内存,CPU会将其缓存-否则会导致性能下降。

操作系统根据需要执行的操作来设置段寄存器,但是无论如何它很少需要四个以上的段。

分段的主要目的(在PM中)是通过为每个程序定义不重叠的分段来实现进程隔离。
一个程序通常只需要一个堆栈段,一个数据段和一个代码段-其他三个段在那里以避免在段最大大小为64KiB时保存/恢复数据段(读:实模式。fsgs稍后添加)。

当今的OS使用平面模型,其中只有两个段(代码和数据/堆栈-这是一个简化,需要其他段)涵盖整个地址空间,另外还包括TLS或PEB / TEB之类的OS特定段。
因此,六个段寄存器甚至比需要的还要多。如果需要(如果是偶数的话),GDT的8192个条目就在那里。