特权级别(ring 0和ring 3)
前言:
大家时常看到ring 0、1、2、3等,那么我们今天来说下这个ring number
x86指令集中的特权级别控制当前在处理器上运行的程序对内存区域、I/O 端口和特殊指令等资源的访问。有 4 个特权级别,从 0(最高特权)到 3(最低特权)。大多数现代操作系统对内核/执行程序使用 0 级,对应用程序使用 3 级。级别 n 可用的任何资源也可用于级别 0 到 n,因此特权级别是环。当权限较低的进程试图访问权限较高的进程时,会向操作系统报告一般保护错误异常。
Linux 和 Windows 仅使用 ring 0 和 ring 3,但其他一些操作系统可以使用三个不同的保护级别。
ring 0(不是字母的o,为是数字的0)
内核是操作系统的核心,可以访问所有内容,可以访问 Ring 0。这里运行的代码被称为内核模式。内核模式进程有可能影响整个系统。
如果这里出现问题,系统很可能会崩溃。因为ring 0可以直接访问CPU和系统内存
ring 1 和ring 2
ring 1 和ring 2 提供了ring 3 所缺乏的独特优势。操作系统使用ring 1 与计算机硬件进行交互。这个戒指需要运行命令,
例如通过我们监视器上的摄像头流式传输视频。必须与系统存储、加载或保存文件交互的指令存储在ring 2 中。 这些权限称为输入和输出权限,因为它们涉及将数据传入和传出工作内存RAM。 例如,在ring 2 中,从存储中加载 Excel 文件文档。在这种情况下,ring 3 将负责编辑和保存数据。
ring 3
以用户模式运行的用户进程可以访问 Ring 3。因此,这是权限最低的ring。这是我们可以找到大部分计算机应用程序的地方。
由于ring 3无法访问CPU或内存,因此涉及这些的任何指令都必须传递给ring 0。
那么它有没有具体的实现呢? 当然有。这需要你了解 GDT(全局描述符表)的条目段描述符
处理器通过识别CPL、DPL、RPL这3种特权级进行特权级检验。
Segment Descriptor(段描述符)
每个段描述符通过指定base 地址和大小来定义虚拟内存区域。此外,还有各种标志位和特权级别(Privilege level)。将 0x100 与段大小进行比较(它必须更小,否则地址在 CS 段之外!)然后添加到base地址以形成“线性”虚拟地址
段描述符表中的每个条目都有一个复杂的结构,我们以结构的方式展现:(x86 and x86-64 segment descriptor)
63 56 | 55 52 | 51 48 | 47 40 | 39 32 |
---|---|---|---|---|
Base 31 24 |
Flags 3 0 |
Limit 19 16 |
Access Byte 7 0 |
Base 23 16 |
31 16 | 15 0 | |||
Base 15 0 |
Limit 15 0 |
我们以计算机存储的方式按位来展现一下
- Base: 一个 32-bit 值,包含段(segment)开始的线性地址。
- Limit: 一个 20-bit的值, 告诉最大可寻址单元, 任何一个以1字节, 或 以 4KiB pages为单位.
因此,如果选page为粒度并将“limit”值设置为0xFFFFF,则在32位模式下该段将跨越整个4GiB地址空间。
在 64-bit模式下, Base 和 Limit 的值是被忽略的, 每个描述符覆盖整个线性地址空间,而不管它们被设置为什么。
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
P | DPL | S | E | DC | RW | A |
- P(bit位):
Present bit. Allows an entry to refer to a valid segment. Must be set (1) for any valid segment. - DPL(bit位): 描述特权等级字段
包含 CPU Privilege level 的 segment. 0 = 最高权限(kernel), 3 = 最低权限 (用户程序).
0和3是linux采用的特权等级 - S(bit位): Descriptor type bit.
If clear (0) the descriptor defines a system segment (eg. a Task State Segment). If set (1) it defines a code or data segment. - E(bit位):
Executable bit. If clear (0) the descriptor defines a data segment. If set (1) it defines a code segment which can be executed from. - DC(bit位):
Direction bit/Conforming bit.- For data selectors: Direction bit. If clear (0) the segment grows up. If set (1) the segment grows down, ie. the Offset has to be greater than the Limit.
- For code selectors: Conforming bit.
- If clear (0) code in this segment can only be executed from the ring set in DPL.
- If set (1) code in this segment can be executed from an equal or lower privilege level. For example, code in ring 3 can far-jump to conforming code in a ring 2 segment. The DPL field represent the highest privilege level that is allowed to execute the segment. For example, code in ring 0 cannot far-jump to a conforming code segment where DPL is 2, while code in ring 2 and 3 can. Note that the privilege level remains the same, ie. a far-jump from ring 3 to a segment with a DPL of 2 remains in ring 3 after the jump.
- RW(bit位): Readable bit/Writable bit.
- For code segments: Readable bit. If clear (0), read access for this segment is not allowed. If set (1) read access is allowed. Write access is never allowed for code segments.
- For data segments: Writeable bit. If clear (0), write access for this segment is not allowed. If set (1) write access is allowed. Read access is always allowed for data segments.
- A(bit位):
Accessed bit. Best left clear (0), the CPU will set it when the segment is accessed.
3 | 2 | 1 | 0 |
---|---|---|---|
G | DB | L | Reserved |
- G(bit位): Granularity flag, indicates the size the Limit value is scaled by. If clear (0), the Limit is in 1 Byte blocks (byte granularity). If set (1), the Limit is in 4 KiB blocks (page granularity).
- DB(bit位): Size flag. If clear (0), the descriptor defines a 16-bit protected mode segment. If set (1) it defines a 32-bit protected mode segment. A GDT can have both 16-bit and 32-bit selectors at once.
- L: Long-mode code flag. If set (1), the descriptor defines a 64-bit code segment. When set, DB should always be clear. For any other type of segment (other code types or any data segment), it should be clear (0).
https://en.wikipedia.org/wiki/Protection_ring
https://www.baeldung.com/cs/os-rings
Linux 和 Windows 仅使用 ring 0 和 ring 3,但其他一些操作系统可以使用三个不同的保护级别。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
2022-04-07 冯·诺依曼计算机体系结构(计算机的历史)
2022-04-07 程序方式获取Linux 内存页基页大小
2022-04-07 进入pod操作,敲错字母,回退问题
2022-04-07 linux中获取堆栈空间大小的方法
2022-04-07 深入网卡
2022-04-07 Linux下编写和加载 .ko 文件(编写linux驱动)