之前看操作系统相关的书籍,都会提到用户态和内核态,由于没有针对特定的操作系统,所以讲解的比较笼统,理解起来也没有很深刻,今天偶然在铜哥桌子上看到了《深入Linux内核框架》这本书,翻起来看了看第一章,感觉还是收获良多,这里对用户态和内核态进行一个简单的总结。
1. 地址空间
学习过操作系统可以知道,在计算机历史上有两个非常成功的抽象,一个是进程,一个是虚拟内存。后者为每个进程提供了一致的地址空间,每一个进程好像独占内存,从而简化了内存的管理。
Linux将虚拟地址空间划分为两个部分,分别是内核空间和用户空间,TASK_SIZE是一个特定于计算机体系结构的常数,把地址空间按给定比例划分为两部分。每个系统进程的用户空间是完全彼此分离的,而虚拟地址空间顶部的内核空间总是同样的,无论当前执行的哪个进程。
2. 特权级别
内核把虚拟地址空间划分为两个部分,因此能够保护各个系统进程,使之彼此隔离。现代cpu都提供了几种特权级别,进程可以驻留在某一特权级别,每个特权级别都有各种限制。
在Linux中有两种不同的状态:核心态和用户态。两种状态的关键差别在于对高于TASK_SIZE的内存区域的访问。简而言之,在用户状态禁止访问内核空间。用户进程不能操作或读取内核空间中的数据,也无法执行内核空间的代码。这是内核的专用领域,这种机制可防止进程无意间修改彼此的数据而造成项目干扰。
从用户态到和内核态的切换通过系统调用的特定转换手段完成,除此之外,还可以由异步硬件中断激活,然后在中断上下文中进行。但是在中断上下文中运行不能访问虚拟地址空间中的用户空间部分。因为中断可能随时发生,中断发生时可能是任一用户进程处于活动状态。由于该进程基本上与中断的原因无关,因此内核无权访问当前用户空间的内容。
3. 总结
总结一下,在虚拟地址空间中会存在内核空间和用户空间,内核空间只有处于内核态的进程才可以访问,可以使用系统调用或者异步硬件中断来实现内核态和用户态之前的切换。
这里补充一点面试中会被问到的知识点,微内核和宏内核。
什么是内核?内核就是硬件与软件之间的中间层,个人理解就是操作系统中的核心部分,而所谓微内核和宏内核指的是操作系统内核设计的两种模式。
微内核:在这种范型中,只有最基本的功能直接由中央内核(微内核)实现,所有其他的功能都委托给一些独立的进程,这些进程通过明确定义的通信接口与中心内核通信。
宏内核:与微内核相反,内核的全部代码都打包在一个文件中,内核中的每一个函数都可以访问内核中所有其他部分。Linux是使用了这种范型。