到目前为止,我对细分的了解是
所以,我的问题是:
根据我所读的内容,将虚拟地址加载到段寄存器中,然后以某种方式从那里继续翻译。在将虚拟地址加载到段寄存器以获得描述符之后,段寄存器会发生什么?
据我了解,段寄存器还保存描述符的缓存值。在翻译过程中如何发挥作用?
鉴于段选择器最多可以具有2 ^ 13个不同的值并且只有六个主寄存器,系统如何确定要加载到哪个段寄存器?
答案 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时保存/恢复数据段(读:实模式。fs
和gs
稍后添加)。
当今的OS使用平面模型,其中只有两个段(代码和数据/堆栈-这是一个简化,需要其他段)涵盖整个地址空间,另外还包括TLS或PEB / TEB之类的OS特定段。
因此,六个段寄存器甚至比需要的还要多。如果需要(如果是偶数的话),GDT的8192个条目就在那里。