Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3

一、现代操作系统的权限分离:

  现代操作系统一般都至少分为内核态和用户态。一般应用程序通常运行于用户态,而当应用程序调用系统调用时候会执行内核代码,此时会处于内核态。一般的,应用程序是不能随便进入内核态的而是需要向OS申请,因为内核态拥有更高的权限。所以当程序运行的时候,其实是有两个栈的,一个位于用户态,一个位于内核态。他们之间会按照操作系统的规定进行通信。

二、用户态切换到内核态的三种方式:

1、系统调用,也即是应用程序使用OS提供的接口调用内核功能。例如x86平台的int 80h和powerrpc的sc等。

2、异常,这是一种被动切换到内核态的方法,当程序在用户态执行时,遇到了未知异常,例如缺页异常。

3、外部中断,也是一种被动切换到内核态的方法,当外设完成用户请求的操作后会发出中断信号,CPU会停止当前进程的调度,转而处理中断处理函数所定义的操作。例如硬盘读写,或者网络IO,此时也会切换进入内核态。

当应用程序进程创建并开始运行时,都处于用户态。当需要用到磁盘、网络读写等操作时候调用操作系统提供接口(系统调用)来进入内核态(方法如上)。然后执行完毕后返回用户态,在这里,一般的应用程序不能随意操作内核态数据,具有一定的保护作用。

三、intel的x86架构分级。

  事实上,类似的分级分层处理机制一直都有,Intel x86架构使用了4个级别来标明不同的特权级权限。R0实际就是内核态,拥有最高权限。而一般应用程序处于R3状态--用户态。在Linux中,还存在R1和R2两个级别,一般归属驱动程序的级别。在Windows平台没有R1和R2两个级别,只用R0内核态和R3用户态。在权限约束上,使用的是高特权等级状态可以阅读低等级状态的数据,例如进程上下文、代码、数据等等,但是反之则不可。R0最高可以读取R0-3所有的内容,R1可以读R1-3的,R2以此类推,R3只能读自己的数据。因为shelllog应该写在内核中。

四、软中断:

  之前在老东家之一的启明工作的时候经常接触软中断的这个概念,也接触软中断就是int 80h,当然这是相对于外部设备的硬中断来说的。今天我终于明白了,所谓的软中断就是系统调用的入口指令,int 80h。

  当真的有进程执行到0x80时候,操作系统首先会保护现场,以便于恢复。这里的本质就是对于堆栈信息和寄存器信息的转存。然后切换特权等级进入内核态,在中断向量表中查询0x80,找到对应的中断处理程序,开始执行中断处理。处理完毕后需要iret从内核态切回用户态。在这个过程中iret会从内核态将之前保存的寄存器、堆栈信息等进程上下文从内核态弹出,以便于恢复到中断之前处理的进程环境,继续执行原程序调度。

原文地址:https://www.cnblogs.com/KevinGeorge/p/8381149.html