Operating System-Chap.2


操作系统 Chap.2 CPU模式 / OS结构

本篇博文我们将更加详细地介绍关于CPU不同模式的实现方式, 以及操作系统的系统结构

1. CPU模式(CPU Mode)

在上篇博文中我们提及过, CPU有两种广为人知的模式:

  • 内核模式(Kernel Mode): 也称为管态(Manager Mode), CPU必须处于此模式才能执行内核代码
  • 用户模式(User Mode): 也称为目态(Usual Mode), CPU通常在这个模式上执行用户代码

1.1 保护环(Protection Ring)

在现在操作系统中, CPU的不同模式是通过 保护环(Protection Ring) 来实现的, 不同等级的保护环代表着不同的权限等级. 通常 保护环等级越低, 权限越高 .

保护环是由上世纪60年代的操作系统: Multics 6400 所引入的概念, 尽管这个操作系统并不成功, 但其引入的许多概念直至今日仍然再为许多操作系统所采用

举例而言, 一个x86架构的CPU, 通常会有以下几种保护环:

  • Ring 0: 内核模式
  • Ring 1: 系统服务
  • Ring 2: 设备驱动
  • Ring 3: 用户模式

Protection Ring

1.2 有必要吗?

为什么操作系统必须衍生出这么多的环? 有何好处?

从分层角度而言, 衍生出不同权限等级的保护环至少有三种好处:

  • Fault Isolation : 即 故障隔离 , 一个在高层环(如Ring 3)的程序崩溃, 不会影响到底层环(如Ring 0)的程序, 同时, 这个故障通常还能够被底层环中的某些代码处理
  • Privileged instructions : 即 特权指令 , 我们在第一章提到过这个概念, 通过不同保护环的划分, 操作系统能够更清晰的明确指令的权限等级, 并将其分配给不同等级的环.
  • Privileged Memory Space : 即 特权内存 , 不同的保护环有不同的内存访问权限. 这有利于内存的划分.

我们通过几个例子来进一步理解上面的说法:

  • 在用户模式下出现的各种问题(Eg. 除0 / 非法访问 / 空指针引用等)能够被内核捕获并抛出异常, 从而不会使得整个系统崩溃.
  • 很多特权指令只能通过内核模式来运行, 用户模式通常会抛出异常(Eg. 在x86架构中, 在Ring 3 中执行特权指令会引发异常: GP (General Protection) exceptions)
  • 某些内存仅有内核模式能够读写(Eg: 在上篇博文中提及的, 用于Multi programming的进程列表等)

我们需要指出, 除Kernel Mode和User Mode外, 还有两个概念: Real Mode 和 Protect Mode , 这两个模式与前两者并不相同, Real Mode 模式下, 并没有保护环的概念, 所有指令都可以执行, 所有内存都可以访问, 它通常被用于早期计算机中; 而Protect Mode 模式下, 引入了保护环机制, 是现代操作系统的基础.

1.3 模式切换(Mode Switch)

如果特权指令的限制如此严格(甚至I/O都是特权指令), 那么用户程序如何能够与硬件进行交互?

通常, 用户程序通过 系统调用(System Call) 来进行模式切换, 进而调用特权指令.

举例而言, printf函数的执行过程:

printf libc call(Ring 3) => write system call => Kernel Mode(Ring 0)

System Call


Root & UnRoot?

明确指出, Root这个概念与Kernel Mode并不是一个概念!

Root 通常指的是一个具有超级权限的用户, 他可以访问所有文件; 而未获得Root权限的用户只能访问系统中的部分文件.

但不论是否是Root用户, CPU都将处于User Mode, 当需要执行特权指令时, 仍然需要通过上文所述的方式进入内核模式.


1.4 保护环 & 虚拟化(Ring & Virtualization)

在介绍本部分之前, 我们需要先引入一个概念: HyperVisor.

A Hypervisor is a Virtual Machine Monitor (VMM) that runs and manages virtual machines

Hypervisor是一个虚拟机监控设备, 负责运行 / 管理全部虚拟机.

因此理论上, HyperVisor所处的保护环层级必须要比虚拟机的操作系统(VM Kernel)要低, 这样其才能控制虚拟机, 或捕获由于虚拟机所产生的异常.

那放哪呢?

传统的方式是 HyperVisor运行在Ring 0, 将 VM Kernel上移到 Ring 1 . 当虚拟机需要运行特权指令时, 通过陷阱(Trap)机制, 由HyperVisor捕获并执行.

这种方式的代价是运行效率的降低, 因为这种陷阱机制需要二进制转译, 额外增加了模式切换的开销.

Full virtualization using Binary Translation

为了解决这个问题, 在2005 / 2006年, Intel和AMD分别推出了一个额外的保护环层级: Ring -1, 这使得虚拟化有了新的构建方式: 将HyperVisor单独运行在Ring -1, 将VM Kernel运行在Ring 0.

这样做的好处在于, 虚拟机系统本身仍处于Ring 0, 因此它与VMM的通信无需进行二进制转译, 这大幅度提高了运行效率.

Full virtualization without Binary Translation


文章作者: MUG-chen
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 MUG-chen !
  目录
加载中...