因此,基于Linux或Windows的x86系统仅将环0用作内核模式,将环3用作用户模式。如果处理器最终只能使用其中两个,为什么还要区分四个不同的环呢?并且这在AMD64架构上发生了变化吗?
因此,基于Linux或Windows的x86系统仅将环0用作内核模式,将环3用作用户模式。如果处理器最终只能使用其中两个,为什么还要区分四个不同的环呢?并且这在AMD64架构上发生了变化吗?
Answers:
有两个主要原因。
第一个原因是,尽管x86 CPU确实提供了四个存储环保护,但是由此提供的保护粒度仅处于每个段级别。也就是说,可以将每个段设置为0到3之间的特定环(“特权级别”),以及其他保护措施(例如禁止写入)。但是没有很多可用的段描述符。大多数操作系统都希望具有更精细的内存保护粒度。喜欢...用于单个页面。
因此,请基于页表项(PTE)输入保护。大多数(如果不是全部的话)现代x86操作系统或多或少都会忽略分段机制(无论如何尽可能),而依赖基于PTE的保护。这由标志位(每个PTE中的低12位)加上支持不执行的CPU上的位63来指定。每页有一个PTE,通常为4K。
这些标志位之一称为“特权”位。该位控制处理器是否必须处于“特权”级别之一才能访问页面。“特权”级别是PL 0、1和2。但是它只有一位,因此在逐页保护级别上,就内存保护而言,可用的“模式”数只有两个:是否可以从非特权模式访问。因此只有两个环。
要为每个页面有四个可能的环,它们将必须在每个页面表条目中具有两个保护位,以对四个可能的环号之一进行编码(就像段描述符一样)。他们没有。
第二个原因是操作系统可移植性的目标。不只是关于x86;Unix告诉我们,一个OS可以相对移植到多种处理器体系结构上,那是一件好事。某些处理器仅支持两个环。通过不依赖体系结构中的多个环,OS实现者使OS更加可移植。
还有第三个原因是Windows NT开发所特有的。NT的设计师(David Cutler和他的团队,Microsoft从DEC Western Region Labs雇来的)具有丰富的VMS经验。实际上,卡特勒和其他一些人都是VMS的原始设计师。为VMS设计的VAX处理器(反之亦然)确实有四个环。VMS使用四个环。(实际上,VAX在PTE中具有四个保护位,允许诸如“从用户模式为只读,但可从环2和内部写入的组合)之类的组合。”
但是,在VMS环1和环2中运行的组件(分别是Record Management Services和CLI)被排除在NT设计之外。VMS中的Ring 2实际上与操作系统的安全性无关,而是与保留用户的CLI环境从一个程序到另一个程序有关,而Windows NT则没有这个概念。CLI作为普通进程运行。对于VMS的环1,环1中的RMS代码必须相当频繁地调用到环0中,并且环转换非常昂贵。事实证明,仅转到环0并用它完成比在环1代码中进行许多环0转换要高效得多。(再次-并不是说NT具有类似RMS的东西。)
但是,为什么他们在那里?至于为什么x86在操作系统不使用它们的情况下实现了四个环,您所谈论的是比x86更新得多的操作系统。x86的许多“系统编程”功能是在NT或真正的Unix-ish内核实现之前就已设计的,他们并不真正了解OS将使用什么功能。(直到我们在x86上进行分页(直到80386才出现),我们才可以实现真正的Unix或VMS风格的内核,而无需重新考虑内存管理。)
现代的x86 OS不仅很大程度上忽略了分段(它们只是将基址为0且大小为4 GB的C,D和S段设置为; F和G段有时用于指向关键OS数据结构),它们还在很大程度上忽略了诸如“任务状态段”之类的东西。TSS机制显然是为线程上下文切换设计的,但事实证明它具有太多的副作用,因此现代的x86 OS可以“手动”完成。例如,x86 NT唯一更改硬件任务的时间是针对某些真正异常的条件,例如双重故障异常。
在x64上,许多这些废弃的功能被遗漏了。(值得称赞的是,AMD实际上与OS内核团队进行了交谈,并询问了他们对x86的需求,他们不需要或不需要的以及他们想要添加的内容。)x64上的段仅存在于称为残留形式,不存在任务状态切换等。并且OS继续仅使用两个环。