Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

内核态与用户态

复习

  • 按下电源:复位与固件:CPU 从约定位置开始执行,固件接过控制权
  • 引导程序与内核加载:引导程序把内核装入内存,内核初始化后接手管理
  • 操作系统是什么:操作系统是资源的管理者和抽象提供者

TL;DR

  • CPU 有两种运行模式:内核态用户态
  • 危险操作只在核态可执行,用户程序只能做受限的事
  • 用户程序要请求内核服务,必须经过受控入口切换到核态
  • 这条界线由硬件保证,是整套保护体系的地基

正文

  上一章说,内核负责管理一切。既然它权力这么大,那普通程序能不能直接对它发号施令,甚至自己动手改内存、关中断、直接操作硬盘?

  如果真能这样,一个写错的程序就足以让整台机器崩溃,一个恶意程序也能偷看别人的数据。系统必须有一道界线。

两种模式

  现代 CPU 提供至少两种运行模式,也叫特权级

  • 内核态(kernel mode):权限最高,可以执行所有指令、访问全部内存
  • 用户态(user mode):权限受限,只能执行普通指令、访问属于自己的内存

  平时我们写的程序,都跑在用户态。

特权指令

  那些“会动到全局”的指令,被划为特权指令,只在核态可以执行。比如:

  • 修改内存映射(谁能访问哪块内存)
  • 开关中断
  • 直接读写设备
  • 让 CPU 停机

  用户程序想干这些事,CPU 会直接拒绝。注意:这道界线不是靠“程序自觉”守住的,而是由 CPU 硬件强行把关——程序根本没法绕过。

怎么跨过界线

  那用户程序要用磁盘、要发网络包,怎么办?总不能永远是用户态。

  答案是:通过受控入口,从用户态陷入内核态。 常见的入口有三类:

  • 系统调用:用户程序主动请求内核帮忙(下一章细讲)
  • 异常:程序自己出了状况,比如除零、访问越界,CPU 转入内核处理
  • 中断:外部设备发来信号,强制 CPU 先处理

  关键在于:用户程序不能自己切到核态,只能“触发一个入口”,由内核决定要不要、以及怎样处理。就像你能走进银行大厅,但要进金库,必须由柜台审核、放行。

一次切换的样子

用户态:程序正常运行
   │  触发系统调用 / 异常 / 中断
   ▼
内核态:内核接管,处理事件
   │  处理完毕
   ▼
用户态:程序继续运行

  这种“用户态→内核态→用户态”的往返,是操作系统里最频繁的动作之一。它带来安全,也带来开销——毕竟换一次“身份”不免费。

  那么,“用户程序主动请求内核帮忙”这件事,到底是怎样正式表达的?这就要说到系统调用

思考题

  假设没有内核态和用户态之分,任何程序都能直接操作硬件。一个普通的文本编辑器,可能会无意中造成哪些严重后果?这条界线保护的是“系统”,还是“程序”?

小结

知识点

  • CPU 有两种模式:内核态与用户态
  • 特权指令只在核态可执行
  • 界线由硬件保证,程序无法绕过
  • 用户程序通过系统调用、异常、中断进入内核态

参考资料

  1. Wikipedia(zh):核心态:内核态与用户态
  2. Wikipedia(zh):特权指令:只允许内核执行的指令
  3. Wikipedia(zh):保护环:CPU 的特权级

思考题答案(仅供参考)

  没有这条界线,一个普通文本编辑器就可能因为一个指针写错,覆盖掉别的程序甚至内核的数据,让整台机器崩溃;恶意程序更能直接读取别人的密码、篡改系统。这条界线表面上是限制程序,实际上是在保护每一个程序:正因为别人不能随便动你的内存、动系统,你自己的程序才有稳定运行的环境。它保护的是整个系统,也就是系统中的每一个程序。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪