谁负责确定进程处于内核模式还是用户模式?我知道内核知道哪个进程属于哪个空间,但 CPU 如何确定呢?我的意思是 CPU 是否应该知道进程或正在执行语句的模式?如果是,该怎么做?如果不是,那么当用户想要做一些被禁止的事情时会发生什么?当我们说用户应用程序只能看到机器资源的子集时,我知道这意味着应用程序不能在 CPU 中执行特定任务,但是谁阻止应用程序执行此类操作,更重要的是如何阻止?
答案1
嗯,这个问题相当有趣。我会尽力帮助你……
谁负责确定进程处于内核模式还是用户模式?
操作系统设计者决定 :-)。所有现代操作系统都以用户模式(x86 架构中“保护模式”中的“ring 3”)运行所有进程,因为这对于使用内存保护和虚拟内存等功能是必要的。较旧和/或较简单的操作系统可能以内核模式(例如 x86 中的“实模式”)运行所有进程;这取决于操作系统设计。例如,MS-DOS 就是这样工作的。
请注意,不同架构(x86、Sparc、PowerPC……)之间处理器模式的实际名称和类型有所不同;但是所有现代处理器都有类似的“保护”模式,可以称之为“用户”模式。
我知道内核知道哪个进程属于哪个空间,但是 CPU 如何确定这一点?
CPU 并不“知道”它,因为 CPU 对进程一无所知;这些是操作系统提供的抽象。CPU 只执行输入的代码。CPU 有在不同模式之间切换的指令,操作系统使用这些指令根据需要将 CPU 置于正确的模式。
例如,在 x86 上,计算机将以“实模式”启动(出于兼容性原因)。当 Linux 或 Windows(NT 及更高版本)等操作系统启动时,它所做的第一件事就是切换到“保护模式”。然后,它使用“环”功能来控制每个程序对硬件的访问。操作系统内核在环 0(完全权限)中运行;用户软件在环 3(受限)中运行。每当操作系统将控制权传递给用户软件时(即当它启动或恢复用户进程时),它将首先切换到环 3。然后控制权交还给内核,CPU 切换回环 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 上的受保护模式下的 ring 3),则代码可能无法执行某些操作(例如访问其分配区域之外的内存)。CPU 知道这一点,并在执行每条指令之前检查可能的违规行为。如果检测到违规,CPU 将停止执行违规代码(这称为“异常”或硬件中断),并跳转到特殊的错误处理代码(由操作系统预先设置)。
这实际上将控制权交还给了操作系统,然后操作系统可以根据需要进行操作:如果异常是由于访问已换出到磁盘的内存而导致的,则从磁盘获取内存(这就是“分页”的工作方式);如果进程非法访问内存(可怕的“保护错误”或“分段错误”),则终止该进程,等等。
答案2
答案3
您的问题的基本答案是:“发生中断时,CPU 会切换到内核模式。”由于操作系统本身在启动过程中设置了中断向量(处理程序),所有这些都指向……内核。进程进行的每个系统调用都只不过是(软件)中断,这意味着调用中断处理程序,而中断处理程序只不过是内核本身(使用寄存器中指定的参数)。
内核在将控制权交给用户进程之前,会设置定时器,使其在一段时间后生成中断,将处理器设置为用户模式,然后将控制权交给用户进程。一段时间后,定时器生成中断,控制权又回到内核。
当然:使用计时器、使用中断向量(处理程序)和使用 CPU 模式都是特权指令,并且允许内核模式进程(即内核本身)执行。