内存保护和地址空间
仅当安全域彼此隔离时,访问控制才有意义。为此,我们需要根据访问权限和能够授予或撤销此类访问权限的特权实体分离安全域的数据。我们将首先查看隔离,稍后在引入保护环时讨论特权。
一个进程通常不应该能够在不经过适当的访问控制检查的情况下读取另一个进程的数据。Multics和几乎所有随后的操作系统(如UNIX和Windows)通过为每个进程提供信息来隔离进程中的信息
(一)它自己的处理器状态(寄存器、程序计数器等)以及(b)它自己的内存子集。每当操作系统决定以牺牲当前正在运行的进程P1(所谓的上下文切换)为代价来执行进程P2时,它首先停止P1和将其所有处理器状态保存在内存中其他进程无法访问的区域。接下来,它将P2的处理器状态从内存加载到CPU中,调整确定物理内存的哪些部分可访问的簿记,并开始在程序计数器指示的地址执行P2,它刚刚作为处理器状态的一部分加载。由于用户进程不能直接操作簿记本身,因此P2无法以非中介形式访问P1的任何数据。
大多数现代操作系统通过页表跟踪内存簿记,如图所示。2.对于每个进程,它们维护一组页表(通常包含组织为有向无环图6的多个级别),并将指向顶级页表的指针存储在寄存器中,该寄存器是处理器状态的一部分,必须在上下文切换上保存和恢复。
页表结构的主要用途是为每个进程提供自己的虚拟地址空间,范围从地址0到某个最大地址(例如,248),即使物理内存量可能要少得多。由于两个进程都可以在地址0x10000存储数据,但不应该允许访问彼此的数据,因此必须有一个来自虚拟的映射。每个进程使用的地址到硬件使用的物理地址。这就像一场篮球比赛,每方可能有一个数字为23的球员,但这个数字被映射到每个球员的不同身体球员身上。团队。
这就是页表的用武之地。我们将每个虚拟地址空间划分为固定大小的页面,并使用页表结构将虚拟页面的第一个字节的地址映射到物理地址。处理器通常使用多个级别的转换。在图例中。2、它使用虚拟地址的前九位作为顶层页表中的索引(由作为处理器状态一部分的控制寄存器指示)来查找包含下一级页表物理地址的条目,该条目由接下来的九位索引,依此类推,直到我们到达最后一级页表,其中包含包含虚拟地址的物理页面的物理地址。虚拟地址的最后12位只是此页面中的偏移量,并指向数据。
分页允许进程的虚拟地址空间的(总)大小远大于系统中可用的物理内存。首先,进程通常不会使用其所有可能的巨大地址空间,只有实际使用的虚拟页面需要物理页面的支持。其次,如果一个进程需要更多的内存来存储一些数据,并且此时没有可用的物理页面(例如,因为它们已经被其他进程使用,或者他们正在支持此过程的其他一些虚拟页面),操作系统可能会将这些页面的内容交换到磁盘,然后重新使用物理页面来存储新数据。
图2:现代处理器中的地址转换。MMU“遍历”页表以查找页面的物理地址。仅当页面“映射”在进程的页表上时,进程才能解决它,假设它存在并且进程具有适当的访问权限权利。具体而言,用户进程无法访问在页表条目中为其设置了主管(S)位的页。
这种组织的一个关键结果是,如果进程的页表中存在映射,则进程只能访问内存中的数据。是否是这种情况,由操作系统控制,因此,操作系统能够准确决定哪些内存应该是私有的,哪些内存应该共享,并且和谁在一起。保护本身由称为内存管理单元(MMU7)的专用硬件实施。如果特定地址的虚拟到物理的映射不在称为事务后备缓冲区(TLB)的小型但非常快速的缓存中,则MMU将通过遍历页表来查找它,然后在包含地址的页面未映射时触发中断。
如果页面当前不在内存中(交换到磁盘),或者与安全性更相关的用户没有访问此内存所需的权限,MMU也会触发中断。具体来说,页表条目(PTE)的最后12位包含一组标志和其中一个标志,即图中的S位。2,指示这是主管代码(例如,以最高权限运行的操作系统)还是普通用户进程的页面。我们稍后会详细介绍特权。
页表是现代操作系统控制内存访问的主要方式。但是,一些(主要是较旧的)操作系统还使用另一个技巧:分段。毫不奇怪,最早同时使用分段和分页的操作系统之一是Multics。与页面不同,段具有任意长度,并从任意地址开始。但是,两者都取决于硬件支持:MMU。例如,英特尔的32位x86等处理器具有一组称为段选择器的专用寄存器:一个用于代码,一个用于数据等。每个段都有特定的权限,例如读取、写入或执行。给定一个虚拟地址,MMU使用相应段选择器中的当前值作为所谓的描述符表中的索引。描述符表中的条目包含段的起始地址和长度,以及保护位,以防止代码没有必需访问它的权限级别。如果只有分段而没有分页,则生成的地址是添加到分段开头的原始虚拟地址,这将是物理地址,我们就完成了。但是,用于Multics的GE-645大型计算机和更现代的x86-32都允许将分段和分页结合起来。在这种情况下,首先使用段描述符表将虚拟地址转换为所谓的线性地址,然后该线性地址使用页表结构转换为物理地址。
这听起来很复杂;没有一个流行的现代操作系统仍然使用分段。使用分段的操作系统最著名的例子是OS/2(微软和IBM之间命运多舛的合作,始于1980年代中期,从未流行过)和IBM的AS/400(也是在1980年代推出的8,今天仍然在您附近的大型机上愉快地运行)。Xen虚拟机管理程序也在32位x86上使用分段,但在64位系统上不再可能。实际上,英特尔x64的66位版本甚至不再支持完全分段,尽管其功能仍然存在一些痕迹。另一方面,复杂的多级地址转换在虚拟化环境中仍然很常见。在这里,虚拟机管理程序试图给虚拟机一种错觉,即它们都在真实硬件上自行运行,因此MMU首先将虚拟地址转换为称为来宾物理地址(使用页表)。但是,这还不是一个真正的物理地址,因为许多虚拟机可能具有使用物理地址0x10000的相同想法。因此,MMU使用第二个转换阶段(使用Intel所说的扩展页表,由虚拟机管理程序维护)将来宾物理地址转换为主机物理地址(“机器地址”)。