内核模式和内存保护

时间:2012-01-29 20:24:02

标签: operating-system kernel osdev

在操作系统用户模式应用程序的虚拟地址空间是私有的,一个应用程序无法更改属于另一个应用程序的数据。每个应用程序都是独立运行的,如果应用程序崩溃,则崩溃仅限于该应用程序。其他应用程序和操作系统不受崩溃的影响

为什么在内核模式下操作系统不保护内存和BOSD发生?

1 个答案:

答案 0 :(得分:8)

首先,在某种程度上,您将始终拥有一个无法失败的组件。如果此组件崩溃,则无法恢复。例如,如果您删除正在运行的进程表,则除了重新启动之外,您无法重建此进程。因此,即使内存保护将此组件的崩溃限制为仅影响其自身,也可能发生BSOD(或等效的)。

但是你的观点很好 - 有许多组件经常可以重置而不会发生灾难性故障。例如,驱动程序或网络堆栈。实际上,有一些操作系统在这个级别上做了保护 - 它们被称为microkernel architectures

然而,微内核的问题在于性能。在x86 CPU上,内存保护通过两件事实现 - Current Privilege Level(CPL或'ring'),0(最大访问)和3(用户模式)之间的数字,以及{{3 }}。页表将虚拟地址映射到物理地址,并在每个页面上设置访问限制(4096字节的内存块)。每个进程都有自己的页表,并且可以通过设置最大CPL,只读标志,无执行标志或无访问标志来限制页表中的每个页面。

更改CPL是一项相对较快的操作(尽管在允许的情况下以及何时允许这样做有安全限制)。但是,更改页表非常昂贵,因为它需要清除CPU上名为Page Table(TLB)的缓存。

通常在正常操作系统中,操作系统将为用户进程保留最低的X GB内存(3GB通常是为32位体系结构选择的数字)。上部(4-X)GB直接映射到物理内存的第一个(4-X)GB,并且仅限于CPL 0(“ring 0”)。因此,无论正在运行什么进程,内核都可以将其私有数据结构放在大约1GB左右,并始终在同一虚拟地址访问它们。如果一个进程发出一个系统调用,需要六个子系统来做某事,没问题 - 你可以在它们之间调用函数。

但是,在微内核系统中,每个内核子系统都有自己的页表和自己的地址映射。为了服务用户调用,CPU可能需要进行相当多的页表更改,并且这种性能提升会增加。此外,每个子系统都需要准备好处理其依赖性的失败,从而增加系统的复杂性。由于存在这些问题,微内核基本上只被用作研究和玩具操作系统(例如,Translation Lookaside Bufferminix)。

尽管如此,近年来,宏核和微核之间存在一些模糊的界限。例如,在Windows 7中,图形驱动程序 实际上与内核的其余部分隔离;如果它崩溃,系统可以恢复。在Linux和OS X中,GNU HURD可以在用户空间中加载文件系统驱动程序;事实上,这些系统上的NTFS驱动程序使用了这种机制。