Answers:
嗯,这个问题很有趣。我会尽力帮助...
谁负责确定进程处于内核模式还是用户模式?
操作系统设计师决定:-)。所有现代OS都在用户模式下运行所有进程(在x86体系结构中,“保护模式”下为“ ring 3”),因为使用诸如内存保护和虚拟内存之类的功能是必需的。较早和/或更简单的OS可以在内核模式下(例如x86中的“实模式”)运行所有进程。这取决于操作系统设计。例如,MS-DOS就是这样工作的。
注意,处理器模式的实际名称和类型在不同体系结构(x86,Sparc,PowerPC ...)之间有所不同。但是,所有现代处理器都具有类似的“保护”模式,这种模式可能称为“用户”模式。
我知道内核知道哪个进程属于哪个空间,但是CPU如何确定呢?
CPU不“知道”它,因为CPU不知道进程。这些是操作系统提供的抽象。CPU仅执行提供给它的代码。CPU具有在不同模式之间切换的指令,并且OS使用这些指令根据需要将CPU置于正确的模式。
例如,在x86上,计算机将以“实模式”启动(出于兼容性原因)。当诸如Linux或Windows(NT及更高版本)的OS启动时,它要做的第一件事就是切换到“保护模式”。然后,它使用“铃声”功能来控制每个程序对硬件的访问。OS内核在环0(全特权)下运行;用户软件在环3中运行(受限制)。每当OS将控制权交给用户软件时(即,当它启动或恢复用户进程时),它将首先切换到Ring3。然后控制权转回到内核,CPU切换回Ring 0。
模式/环之间的切换究竟如何工作取决于CPU体系结构。大多数体系结构提供了用于切换的特殊指令或机制。一旦将CPU切换到某个模式/环,它将自行跟踪该模式(以及任何相关的限制)。
有关在x86架构上如何工作的详细信息,请参见本文:http : //duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection
顺便说一句:受限CPU模式下的保护/限制主要由CPU的内存管理单元实现。较旧和/或更简单的处理器(例如Amiga和Atari ST使用的Motorola 68000或C64的6510)没有MMU。因此他们不能运行区分内核和用户模式的操作系统。例如,这就是为什么Linux m68k端口至少需要运行Motorola 68020处理器的原因。较早的68000和68010没有MMU。
我的意思是CPU应该知道进程或执行语句的模式吗?如果是,怎么办?
是的,从某种意义上说,CPU知道了这一点,尽管它不知道为什么。
如果没有,那么当用户要禁止做某事时会发生什么?当我们说用户应用程序只能看到一部分机器资源时,我知道这意味着应用程序无法在CPU中执行特定任务,但是谁阻止了应用程序执行此类任务,更重要的是如何停止呢?
一个很好的问题。CPU本身会停止应用程序。
如果代码(应用程序)在特权受限的模式下运行(例如x86上处于保护模式的环3),则代码可能存在某些无法做的事情(例如访问分配了代码的区域之外的内存)。CPU知道这一点,并在执行前检查每条指令是否存在违规情况。如果检测到违规,则CPU停止执行有问题的代码(这称为“异常”或硬件中断),并跳转到特殊的错误处理代码(由OS预先设置)。
这可以有效地将控制权交还给OS,然后可以按其认为合适的方式进行操作:如果异常是由于访问已换出到磁盘的内存(这是“分页”的工作原理)导致的,则从磁盘中获取内存,然后终止进程它非法访问内存(可怕的“保护错误”或“分段错误”),等等。
问题的基本答案是:“发生中断时,CPU切换到内核模式。”。操作系统本身正在设置,在引导过程中设置了中断向量(处理程序),所有这些都指向...内核。进程进行的每个系统调用都不过是(软件)中断,这意味着调用中断处理程序,而该处理程序只不过是内核本身(在寄存器中指定了参数)。
内核在将控制权交给用户进程之前,先设置计时器以在一段时间后生成中断,然后将处理器设置为用户模式,然后再将控制权交给用户进程。一段时间后,计时器将生成中断,并将控制权返回给内核。
当然:使用计时器,使用中断向量(处理程序)和使用cpu模式都是特权指令,并允许它们进入内核模式进程(即内核本身)。