此文章参考了
简答来说,用户态和核心态的区别就是:两者的操作权限不同,用户态的进程能够访问的资源受到了极大的控制,而运行在内核态的进程可以“为所欲为”。我们所说的内核,它本质上是一种特殊的软件程序,特殊在哪儿呢?控制计算机的硬件资源,例如协调CPU资源,分配内存资源。
而用户态就是提供应用程序运行的空间,为了使应用程序访问到内核管理的资源例如CPU,内存,I/O。内核必须提供一组通用的访问接口,这些接口就叫系统调用。比如用户态想要申请一块20K大小的动态内存,就需要brk系统调用指令。
从用户态到核心态可以有三种方法:
1、 系统调用,这个上面已经讲解过了。其实系统调用本身就是中断,但是软件中断,跟硬中断不同。
2、异常:如果当前进程运行在用户态,如果这个时候发生了异常事件,就会触发切换。例如:缺页异常。
3、外设中断:当外设完成用户的请求时,会向CPU发送中断信号。
那么具体的切换过程是什么呢?简单来说是:
1、当前进程在用户态用汇编指令 int <中断向量号> 发出中断请求,这个中断请求里面有中断向量。在系统内存中存放着“中断向量表”,这个中断向量表里面存放着各种中断描述符,中断描述符里存放着中断服务函数的入口地址,以及他所需要的特权级别,内核态的特权级为0,用户态为3。
2、CPU 在总线上捕捉到中断向量 ,通过寄存器 IDTR (里面保存了中断向量表的首地址和长度)找到中断向量表,然后找到中断向量对应的中断描述符,进行权限的验证。
3、如果权限符合(中断描述符里面一般有四类中断服务函数是用户态可以调用的:断点、溢出、边界检查、系统调用),接下来用户栈切换到内核栈,因为这两个栈里面保存的代码和数据都是不同的,切换的关键在于栈地址的切换,而用户栈和内核栈的栈地址都保存在了”任务状态段“TSS中。从用户栈切换到内核栈之后,就完成了从用户态到核心态的切换(之后可能就要去执行中断服务函数了)。
更为具体的内容参考上面的网站。