聊聊内核态和用户态
CPU指令分类
在CPU所有指令中,有些指令是非常危险的,例如内存清除、设置时钟等,错误使用会导致系统崩溃。如果所有程序都可以使用这些指令,系统崩溃的概率将大大增加。所以CPU将指令分为特权指令和非特权指令,对于危险指令,只允许操作系统及其相关模块使用,普通应用程序只能使用那些不会造成灾难的指令。例如intel将CPU访问等级分为ring0-ring3。Linux只用到ring0(进程运行在ring0级别就称为运行在内核态)和ring3(用户态)。用户态只能访问用户应用进程的资源。而内核态几乎可访问操作系统一切敏感资源。
用户态切换到用户态的方式
有三种切换方式:
1、系统调用。用户态进程主动切换到内核态的一种方式,用户态进程通过系统调用,向操作系统申请资源完成工作,如访问磁盘。系统调用的机制核心,还是使用了操作系统为用户特别开放的一个中断来实现;
2、中断。CPU正在执行用户进程指令,当外围设备完成用户请求的操作后,会对CPU发起中断信号,CPU会暂停执行下一条指令,然后转到和中断信号对应的处理程序去执行,也就是切换到了内核态。如硬盘读写完成,操作系统会切换到硬盘读写的中断,处理程序中执行后边的操作;
3、异常。用户态进程在执行时,发生事先不可知的异常,此时会触发由当前运行进程切换到处理此异常的内核相关进程中,也就是从用户态切换到内核态,比如缺页异常。在系统处理上,中断和异常类似,都是从中断向量表找到相应的处理程序进行处理,区别在于中断来源于外部,不是由任何一条专门的指令造成,而异常是当前执行指令的结果),操作系统做相应的系统调用,将执行结果返回给应用程序时,就从内核态切换回用户态;