什么是用户态和内核态
Kernel 运行在超级权限模式(Supervisor Mode)下,所以拥有很高的权限。按照权限管理的原则,多数应用程序应该运行在最小权限下。因此,很多操作系统,将内存分成了两个区域:
内核空间(Kernal Space),这个空间只有内核程序可以访问;
用户空间(User Space),这部分内存专门给应用程序使用。
用户态和内核态
用户空间中的代码被限制了只能使用一个局部的内存空间,我们说这些程序在用户态(User Mode) 执行。内核空间中的代码可以访问所有内存,我们称这些程序在内核态(Kernal Mode) 执行。
系统调用过程
如果用户态程序需要执行系统调用,就需要切换到内核态执行。下面我们来讲讲这个过程的原理。
如上图所示:内核程序执行在内核态(Kernal Mode),用户程序执行在用户态(User Mode)。当发生系统调用时,用户态的程序发起系统调用。因为系统调用中牵扯特权指令,用户态程序权限不足,因此会中断执行,也就是 Trap(Trap 是一种中断)。
发生中断后,当前 CPU 执行的程序会中断,跳转到中断处理程序。内核程序开始执行,也就是开始处理系统调用。内核处理完成后,主动触发 Trap,这样会再次发生中断,切换回用户态工作。
CPU在执行指令的时候又没办法区分这条指令是应用程序的还是操作系统的,它只是一个没有感情的执行机器,只会闷头执行···
为了解决这个问题,x86 CPU搞了个特权级出来,或者说是CPU提供了四个工作模式,从Ring0-Ring3,每一个模式又称为一个环,一共四个环。0环是最高权限模式,可以执行所有指令。Ring3是最低权限模式,只能执行指令集中的一部分指令。
也就是说,CPU搞了四个工作模式出来,只有工作在Ring0模式下,才能执行上面的那些特权指令,在其他模式下如果要去执行那些指令,CPU就会抛出异常!
有了CPU的这一硬件技术支持,问题就好办了,我们可以让CPU在执行操作系统代码的时候运行在Ring0模式,在执行普通应用程序代码的时候运行在Ring3模式,这样就解决了特权指令的问题。
内核地址空间
那个问题来了:CPU如何知道现在执行的代码是不是操作系统的呢?
把操作系统的代码放在内存中一个特殊的区域,当CPU执行的指令地址来自这个区域时,就切换工作模式到Ring0【工作模式保存在CPU的状态寄存器】,离开这个区域后,就切换到其他模式。
光这样还不够,还得加一个措施:这个区域不能让应用程序来访问,否则谁都能来读写,那还了得?
所以,除了指令增加特权级以外,在内存的访问上,也得加上特权级。
这个特殊的区域就是内核地址空间!一般位于进程地址空间中较高的区域,以32位下Windows为例,它是在0x80000000~0xFFFFFFFF这个区域。我们把位于这个空间中的代码叫做操作系统的内核代码,有时候也简称内核。而把应用程序代码所活动的区域叫做用户地址空间。
进一步,我们常把CPU执行内核代码的模式称为内核态,把执行用户程序时的模式称为用户态。
https://mp.weixin.qq.com/s/0epXchOU0Q-2jzETY_aMJQ
https://kaiwu.lagou.com/course/courseInfo.htm?courseId=478#/detail/pc?id=4621