计算机系统:程序员的视角说
为了使操作系统内核提供严密的进程抽象,处理器必须提供一种机制来限制应用程序可以执行的指令以及它可以访问的地址空间部分。
处理器通常通过某些控制寄存器中的模式位来提供此功能,该模式位表征进程当前享有的特权。当模式位被设置时,进程在内核模式(有时称为管理模式)下运行。运行在内核模式下的进程可以执行指令集中的任何指令并访问系统中的任何内存位置。
当模式位未设置时,进程在用户模式下运行。用户模式下的进程不允许执行诸如停止处理器、更改模式位或启动 I/O 操作之类的特权指令。也不允许直接引用地址空间的内核区域中的代码或数据。任何此类尝试都会导致致命的保护故障。用户程序必须通过系统调用接口间接访问内核代码和数据。
运行应用程序代码的进程最初处于用户模式。进程从用户模式更改为内核模式的唯一方法是通过异常,例如中断、故障或捕获系统调用。当异常发生并且控制权传递给异常处理程序时,处理器将模式从用户模式更改为内核模式。该处理程序在内核模式下运行。当它返回到应用程序代码时,处理器将模式从内核模式更改回用户模式。
如果一个用户态进程想要改变到内核态,它总是能成功吗?
模式改变是否成功取决于进程改变到内核模式后想要做什么?
举些例子,
进程可能有权也可能没有访问文件的权限,具体取决于进程的 uid 和文件的访问控制位。当进程发出系统调用来访问文件时,它是否总是能够成功地从用户模式更改为内核模式?进程能否从用户态转为内核态取决于能否访问该文件?
sudo
与进程是否可以从用户模式更改为内核模式无关吗?
谢谢。
答案1
进程能否从用户态转为内核态取决于能否访问该文件?
不,检查程序是否可以访问文件发生在内核中。程序可以在需要使用中断(在 x86 中)或syscall
指令(在 amd64 中)时调用内核。
sudo 与进程是否可以从用户模式更改为内核模式无关吗?
sudo
与用户模式/内核模式无关。超级用户帐户仍然仅存在于用户模式中。
答案2
如果一个用户态进程想要改变到内核态,它总是能成功吗?
出于所有实际目的,是的。请注意,进程不一定“想要”更改为内核模式 - 每当进程尝试特权操作或调用特权“门”时,处理器都会切换到内核模式。
特权操作的构成细节是特定于体系结构的,但从广义上讲,它们包括:
- 特权指令,以不应受非内核控制的方式影响全局系统状态(x86 上的示例包括
CLI
禁用不可屏蔽中断的指令和HLT
停止 CPU 的指令); - 某些类型的输入/输出指令,这取决于权限级别(在 x86 上,指令
IN
/OUT
系列); - 尝试访问当前进程不允许访问的内存;
- 尝试在当前进程不允许执行的内存区域中执行代码。
其他指令或情况也将最终陷入内核或出现故障,而不必是特权本身 - 例如,尝试除以零。
如果切换到内核模式所需的信息未正确设置,处理器将出现故障,如果该故障未正确处理,通常会重新启动。 (看双误和三重错误.)
如果您想了解更多信息,请参阅相关的处理器手册(例如 英特尔手册)。
在 x86-64 上,SYSCALL
用于调用系统调用的指令位于“常规”指令和特权指令之间;它始终是可调用的,并且始终以特权模式调用代码。
模式改变是否成功取决于进程改变到内核模式后想要做什么?
不。
当进程发出系统调用来访问文件时,它是否总是能够成功地从用户模式更改为内核模式?进程能否从用户态转为内核态取决于能否访问该文件?
不,切换到内核模式发生在任何内核代码运行之前,包括决定是否允许调用者执行其要求执行的操作。
sudo
与进程是否可以从用户模式更改为内核模式无关吗?
不是。这里的权限只涉及处理器的执行级别和内存保护;它们与用户权限(例如用户/root 区别)完全分开。
答案3
内核空间中有明确定义的入口点。
存在一个表(仅在内核模式下可写)。它包含许多例程的起始地址。其中包括出现分段错误、除以零、硬件中断、系统调用等时运行的例程。
因此,进程可以通过执行系统调用(可能有 1 个或多个)指令来触发转换。然而,用户模式代码无法指定运行什么代码。在系统调用中,内核模式将查看寄存器的内容,以确定进程想要什么,它将查看进程的用户、组、功能等来决定是否可以做到这一点。