赞
踩
参考资料:
用户态和内核态是操作系统的两种运行状态。
内核态:处于内核态的 CPU 可以访问任意的数据,包括外围设备,比如网卡、硬盘等,处于内核态的 CPU 可以从一个程序切换到另外一个程序,并且占用 CPU 不会发生抢占情况,一般处于特权级 0 的状态我们称之为内核态。
用户态:处于用户态的 CPU 只能访问受限资源,不能直接访问内存等硬件设备,不能直接访问内存等硬件设备,必须通过「系统调用」陷入到内核中,才能访问这些特权资源。
在 CPU 的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃,比如:清空内存,修改时钟等。如果所有的程序代码都能够直接使用这些指令,那么很有可能我们的系统一天将会死 n 次。
所以,CPU将指令分为 特权指令 和 非特权指令 ,对于较为危险的指令,只允许操作系统本身及其相关模块进行调用,普通的、用户自行编写的应用程序只能使用那些不会造成危险的指令。
基于安全的考虑,CPU 提供了特权分级机制,把区域分成了四个 Ring,越往里权限越高,越往外权限越低。
操作系统根据 CPU 的特权分级机制,把进程的运行空间分为「内核空间」和「用户空间」,分别对应着上图中, CPU 特权等级的 Ring 0 和 Ring 3。
有三种方式程序会从用户态陷入内核态:
这3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程「主动」发起的,异常和外围设备中断则是「被动」的。
当程序需要访问硬件资源的时候,比如内存、硬盘等,就需要通过「系统调用」陷入到内核中,才能访问这些特权资源。系统调用可以理解为内核实现的函数,比如应用程序要通过网卡接收数据,会调用 Socket 的 read 函数。
程序在执行系统调用的过程中会从用户态切换到内核态,再从内核态切换到用户态,过程如下:
系统调用的过程:
一次系统调用过程中的,会发生两次「 CPU 上下文切换」(所谓的 CPU 上下文就是 CPU 寄存器和程序计数器):
Linux 系统中每个进程都有两个栈,分别是用户栈和内核栈,当应用程序运行在用户态的时候,就会使用用户栈,当应用程序运行在内核态的时候,就会使用内核栈。
内核态与用户态的相互切换,其中最重要的一个步骤就是用户栈和内核栈的切换。
1、用户栈到内核栈:
2、内核栈到用户栈
iret
指令。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。