用户态和内核态值得是程序状态。
用户态和内核态是什么
CPU给不同的指令和寄存器规定了不同的特权级。内核态和用户态其实就是高特权级与低特权级。
Intel CPU将CPU指令集操作权限由高到低分为0、1、2、3。
0表示高特权级,内核处于高特权级。3表示低级权限,用户进程属于低特权级。
CPU能知道当前执行者属于哪种特权级,也知道要执行的指令属于哪种特权级。但并不知道当前执行的是内核代码还是用户进程代码。内核和用户进程属于程序员的概念。
对于CPU而言,当前执行者就是cs:eip,它指向了待执行的那条指令。当前指令属于哪个特权级是已知的,只需要判断【当前执行者】的特权级,特权级保存在cs寄存器的最低两位。
段寄存器 最低两位如果是00则为内核代码,11则为用户进程代码 段寄存器不止CS、比如DS、SS等。
用户态
对CPU而言,段寄存器最低两位是11时就是用户态。用户态就是CPU运行用户程序。
内核态
对CPU而言,段寄存器最低两位是00时就是内核态。内核态就是CPU运行操作系统程序。
需要通过系统调用来请求操作系统,必须在内核态特权级下执行指令。
系统调用比如读取硬盘的数据、内存分配、网卡、声卡等。
用户态和内核态怎么切换
段寄存器的最低两位从00改为11。
用户态切换内核态三种方式
- 中断
通过触发中断,用户发出了系统调用的中断指令,那么此时将会从用户态陷入内核态,不过当中断处理程序执行完之后,又会通过中断返回指令从内核态回到用户态。
中断和中断返回可以单独使用,没有中断也能中断返回。
-
系统调用
2.1 进程调用
exit、fork
2.2 文件系统访问
chmod、chown、open
2.3 设备调用
read、write
2.4 信息读取
getxx
2.5 通信
申请内存mmap、进程间通信pipe
-
异常
用户态切换内核态过程
(用户态 - 内核态 - 用户态),其实发生了两次CPU上下文切换。
-
保留用户态
上下文、寄存器、用户栈等
-
复制用户态参数,用户态切到内核态,进入内核态
-
额外的检查
因为内核代码对用户不信任
-
执行内核态代码
-
复制内核态代码执行结果,回到用户态
-
恢复用户态现场
上下文、寄存器、用户栈等
用户态切内核态产生问题
性能问题
- 数据拷贝
因为用户态切换至内核态后还需要切回用户态,因此用户栈的信息需要保存/将寄存器中的数据保存到县城所属的某块内存区域
- 安全验证
用户态切换到内核态还需要安全验证等操作。
其他
用户内核态切换和上下文切换的关系