MelonBlog

浅谈是内核态和用户态

我们会常听到内核态用户态这两个词,特别是一些讲线程相关的技术文章,今天来简单讲讲什么是用户态和内核态。

用户态和内核态的由来

早期的计算机,所有程序都运行在同一个空间,运行在计算机上面的程序一但出bug,不仅会导致程序出问题,还会直接影响到操作系统甚至机器本身。

所以计算机科学家们想了一个办法,为了让程序因为bug崩溃的时候,不影响操作系统和机器,他们把用户程序和操作系统从逻辑上隔离了起来,用户程序运行的区域称为用户态,操作系统运行的区域称为内核态。两块区域在正常情况下互不干扰,但是也有一些机制可以保证两块区域之间的数据交互。

特权模式和非特权模式

不同的操作系统的限制也不同,例如MS-DOS系统,允许用户直接访问硬件,但是Unix-like系统会限制用户程序访问硬件资源。

在现代操作系统中,用户程序如果想要访问必须委托内核程序,只有内核才能和硬件交互。为了实现这种隔离机制,硬件上也做了相应的设计,例如CPU分为两种执行模式。一种是特权模式,专门提供给内核程序使用,另一种是非特权模式,用于用户程序使用。这两种特权模式在Unix中也被称为内核模式用户模式

image

保护环(Protection Rings)

不同的操作系统实现资源控制的粒度不一样,一般来说操作系统会把权限分为几层。如图所示,不同的权限等级可以想象成多个嵌套的环,最内层的环称为Ring 0,最外层为Ring 3。Ring 0拥有最高的权限级别,能够直接访问硬件,例如CPU和内存,Ring 3则是提供给用户程序使用的权限级别。

image

用户态和内核态的切换

不让用户态的程序访问硬件,确实能够大大降低操作系统崩溃的风险。但是用户程序有时候又必须获取硬件的资源,比如读取磁盘里面的数据。

必须有那么一个机制让用户态程序能够安全的和硬件资源交互。操作系统提供了这么一个机制—系统调用(System Call)

系统调用是操作系统在内核模式下执行的一系列特殊函数,可以理解成操作系统提供用户程序使用的api接口。