少于 1 分钟阅读 次阅读

概要:介绍 x86 的特权级体系:Ring 0(内核态)与 Ring 3(用户态)的概念,以及 CPL(存放在 %cs 中)与 DPL(存放在段描述符中)的硬件实现和“门禁核验”规则。

1. Ring 0 和 Ring 3:CPU 的“阶级地位”

Intel 的 x86 架构本来设计了四个特权级别(Ring 0 到 Ring 3),数字越小,权力越大。但后来像 Linux 和 Windows 这些现代操作系统嫌麻烦,觉得四层太复杂了,干脆只用了最高和最低的两个级别:

  • Ring 0(内核态):这就像是“上帝模式”或者系统里的“超级管理员”。运行在这个级别的代码(通常是操作系统内核、底层硬件驱动)拥有最高权限,可以直接操控各种硬件、管理所有内存。要是 Ring 0 的代码写飞了,那整个系统就直接蓝屏或者死机了。
  • Ring 3(用户态):这就像是普通的“打工人”。咱们平时写的业务代码,或者跑的 QQ、浏览器,全都在 Ring 3 跑着。这个级别的权限被锁得死死的,不能直接碰硬件。如果 Ring 3 的程序想读写硬盘或者收发网络数据,必须老老实实地向 Ring 0 “打报告”(也就是发起系统调用),让 Ring 0 帮忙去做。
        ┌──────────┐
        │  Ring 3  │  ← 普通用户程序(权限最低)
        │ ┌──────┐ │
        │ │Ring 0│ │  ← 操作系统内核(权限最高)
        │ └──────┘ │
        └──────────┘

2. CPL (Current Privilege Level):你手里拿的“当前门禁卡”

CPL 就是当前正在执行的代码的权限级别

还记得咱们刚才说的 %cs 代码段寄存器吗?在保护模式下,%cs 寄存器最低的那两位(第 0 位和第 1 位)存放的就是 CPL。

  • CPU 每执行一条指令,它都知道自己现在的 CPL 是几。
  • 如果这两位是 00(也就是 0),说明当前代码正拿着 Ring 0 的顶级门禁卡。
  • 如果是 11(也就是 3),说明当前代码手里只有 Ring 3 的普通门禁卡。

3. DPL (Descriptor Privilege Level):房间门上的“安全要求”

DPL 是目标内存段或者资源本身要求的权限级别

内存里不是分了很多段嘛,每个段在全局描述符表(GDT)里都有一个对应的描述符(Descriptor)。这个描述符里面记录了这个段的各种信息,其中就包括 DPL。

  • DPL 就像是贴在房间门上的安全等级要求。比如某个存放系统核心数据的内存段,它的 DPL 被设为了 0,意思就是“级别没到 0 的人禁止入内”。

它们是怎么互动的?(门禁核验)

这就到了查门禁的时候了。当你(当前的程序)想要去访问某一块内存,或者跨段跳转时,CPU 硬件在底层会自动把你的 CPL(你手里的卡)和目标位置的 DPL(门上的要求)拿来对比:

  • 只有当你的 CPL 数值小于或等于 DPL 的数值时(数值越小权限越大,也就是你的特权得比门锁要求的高,或者一样高),CPU 才会放行。
  • 如果一个 CPL 是 3 的普通程序,非要硬闯 DPL 是 0 的内核内存段,CPU 硬件立马就会翻脸,直接拦截并抛出一个异常(一般叫 General Protection Fault)。操作系统内核收到这个异常后,通常会无情地把这个不守规矩的程序给杀掉(这时候你可能就会看到程序崩溃退出了)。

简单来说,Ring 0 和 Ring 3 是等级划分的概念,而 CPL(在 %cs 里)和 DPL(在内存描述符里)是这套规则在硬件上的具体实现

留下评论