内核模式和内存保护

5
在操作系统中,用户模式应用程序的虚拟地址空间是私有的,一个应用程序无法更改属于另一个应用程序的数据。每个应用程序都在隔离环境中运行,如果一个应用程序崩溃,崩溃只限于该应用程序。其他应用程序和操作系统不会受到影响。
为什么在内核模式下操作系统不保护内存,会发生蓝屏死机呢?

这对我来说听起来像是一个关于操作系统开发的话题。 - bdonlan
1个回答

8

首先,某个层次上,您将始终拥有一个不可能失败的组件。如果此组件崩溃,则无法进行恢复。例如,如果您损坏了正在运行的进程表,除了重新启动外,您无法重建它。因此,即使内存保护限制了此组件仅影响自身的崩溃,仍可能发生蓝屏死机(或等效情况)。

但您的观点是正确的-有许多组件通常可以在没有灾难性故障的情况下重置。例如,驱动程序或网络堆栈。实际上,有些操作系统在这个层面上进行保护-它们被称为 微内核架构

然而,微内核的问题在于性能。在x86 CPU上,内存保护需要两个东西 - 当前特权级(CPL或'ring'),一个介于0(最大访问权限)和3(用户模式)之间的数字,以及页表。页表将虚拟地址映射到物理地址,并对每个页面(4096字节的内存块)设置访问限制。每个进程都有自己的页表,页表中的每个页面都可以通过设置最大CPL、只读标志、不执行标志或无访问标志来受到限制。
改变CPL是一个相对较快的操作(尽管在何时以及如何允许这样做方面存在安全限制)。然而,改变页表是非常昂贵的,因为它需要清除CPU上的缓存,称为翻译后备缓冲器(TLB)。
通常在正常的操作系统中,操作系统会为用户进程保留最低的X GB内存(32位架构通常选择3GB)。上部(4 - X)GB直接映射到物理内存的前(4 - X)GB,并且仅限于CPL 0('ring 0')。因此,内核可以将其私有数据结构放在上1GB左右,并始终以相同的虚拟地址访问它们,无论运行哪个进程。如果一个进程发出需要半打子系统执行某些操作的系统调用,没有问题-您可以在它们之间调用函数。
然而,在微内核系统中,每个内核子系统都有自己的页表和地址映射。为了服务于用户调用,CPU可能需要进行相当多的页表更改,这种性能损失会累积。此外,每个子系统都需要准备好处理其依赖项的故障,增加了系统的复杂性。由于这些问题,微内核大体上只被用作研究和玩具操作系统(例如minixGNU HURD)。
在最近几年中,宏内核和微内核之间的界限有些模糊。例如,在Windows 7中,图形驱动程序实际上与内核的其余部分隔离; 如果它崩溃了,系统可以恢复。在Linux和OS X中,FUSE可以在用户空间加载文件系统驱动程序;事实上,在这些系统上的NTFS驱动程序使用了这种机制。

谢谢bdonlan。但我的问题很简单。我想知道“为什么操作系统在内核模式下不隔离内存(针对每个组件和KMD)?” - A S
@AS,我已经解释过了。微内核确实隔离内存。只是因为这个原因它们比较慢。 - bdonlan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接