进入内核态究竟是什么意思?

知乎上有一个问题:
进入内核态究竟是什么意思?
文章图片
进入内核态究竟是什么意思?
暂且忘记这个问题 , 让我们从另一个问题出发 , 一步步引出这个问题的答案 。
特权指令问题
现代计算机里面 , 同时运行了很多程序 , 比如Office软件、浏览器、QQ、还有你现在正在看这篇文章的微信 , 这些程序运行起来就是一个个的进程 , 每个进程都有各自的内存地址空间 , 为了防止大家越界 , 大打出手乱了规矩 , 得要有个管家来管理大家 , 这个管家就是操作系统 。
好了 , 不管是前面说的那些应用程序 , 还是操作系统 , 本质上都是CPU去执行的二进制程序指令吧 , 而一个CPU能够执行的所有指令都在它的指令集里面了 。
试想一下 , 假如指令集中的所有指令都一视同仁 , 任何程序都可以使用这些指令 , 那会出现什么问题?
那操作系统的权威性如何保证?怎么管理这一堆进程 , 还不反了天了?因为谁都可以执行这些指令 , 大家都是平起平坐啊!
所以 , 必须将指令集中的一部分比较敏感的划出来 , 这部分只能让操作系统来执行 , 其他程序不能执行 , 以此来捍卫操作系统的地位!
哪些指令比较敏感?
涉及到操作系统管理计算机资源的指令就是敏感指令 。
以x86架构的CPU为例 , 中断的打开与关闭、外部设备的输入与输出、进程地址空间基地址CR3寄存器的修改、中断描述符表IDT基地址寄存器的修改、全局描述符表LDT基地址寄存器的修改···这些都是敏感操作 , 是普通应用程序绝对不能碰的指令:
clistiinoutlidtlgdt···那如何做到让这些敏感指令操作系统能够执行 , 而普通程序又不能执行呢?
CPU在执行指令的时候又没办法区分这条指令是应用程序的还是操作系统的 , 它只是一个没有感情的执行机器 , 只会闷头执行···
为了解决这个问题 , x86CPU搞了个特权级出来 , 或者说是CPU提供了四个工作模式 , 从Ring0-Ring3 , 每一个模式又称为一个环 , 一共四个环 。 0环是最高权限模式 , 可以执行所有指令 。 Ring3是最低权限模式 , 只能执行指令集中的一部分指令 。
进入内核态究竟是什么意思?
文章图片
也就是说 , CPU搞了四个工作模式出来 , 只有工作在Ring0模式下 , 才能执行上面的那些特权指令 , 在其他模式下如果要去执行那些指令 , CPU就会抛出异常!
有了CPU的这一硬件技术支持 , 问题就好办了 , 我们可以让CPU在执行操作系统代码的时候运行在Ring0模式 , 在执行普通应用程序代码的时候运行在Ring3模式 , 这样就解决了特权指令的问题 。
内核地址空间
但这里又回到之前那个问题了:CPU如何知道现在执行的代码是不是操作系统的呢?
一个最容易想到的解决办法就是:把操作系统的代码放在内存中一个特殊的区域 , 当CPU执行的指令地址来自这个区域时 , 就切换工作模式到Ring0 , 离开这个区域后 , 就切换到其他模式 。
光这样还不够 , 还得加一个措施:这个区域不能让应用程序来访问 , 否则谁都能来读写 , 那还了得?
所以 , 除了指令增加特权级以外 , 在内存的访问上 , 也得加上特权级 。
x86架构的CPU是基于分段式+分页式相结合的内存管理方式 , 所以Intel倒腾了几下 , 给不同的内存段限定了不同的访问模式 , 并把它记录到了段的描述符中 。
在访问内存的时候 , CPU就会拿当前段寄存器中标示的权限和要访问的目标内存所在段段访问权限进行对比 , 符合要求才能访问 , 否则也会抛出异常!