CPU的所有指令中,有些指令是非常危险的,如果错用,将导致系统崩溃,比如清内存、设置时钟等。如果允许所有的程序都可以使用这些指令,那么系统崩溃的概率将大大增加。所以,CPU将指令分为特权指令和非特权指令,对于那些危险的指令,只允许操作系统及其相关模块使用,普通应用程序只能使用那些不会造成灾难的指令。
Linux系统只使用了Ring0和Ring3两个运行级别。当进程运行在 Ring3 级别时被称为运行在用户态,而运行在 Ring0 级别时被称为运行在内核态。运行在Ring3级别时被称为运行在用户态,运行在Ring0级别时被称为运行在内核态。 在内核态下,进程运行在内核地址空间中,此时 CPU 可以执行任何指令。运行的代码也不受任何的限制,可以自由地访问任何有效地址,也可以直接进行端口的访问。 在用户态下,进程运行在用户地址空间中,被执行的代码要受到CPU的检查,它们只能访问映射其地址空间的页表项中规定的在用户态下可访问页面的虚拟地址,且只能对任务状态段中I/O许可位图中规定的可访问端口进行直接访问。
我们可以将每个处理器在任何指定时间点上的活动概括为下列三者之一:
运行于用户空间,执行用户进程。运行于内核空间,处于进程上下文,代表某个特定的进程执行。运行于内核空间,处于中断上下文(保证中断服务程序能够在第一时间响应和处理中断请求,然后快速地退出),与任何进程无关,处理某个特定的中断。 用户态到内核态的转换概况来说有三种方式分别为系统调用、软中断和硬件中断。从内核空间和用户空间的角度看整个Linux系统的结构,从下往上依次为:硬件 -> 内核空间 -> 用户空间