内核是操作系统的核心组件 。 内核也被认为是操作系统的核心。 它负责管理所有进程,内存,文件等。 内核功能在操作系统的最低级别。 它充当用户级应用程序(软件)和硬件之间的接口(桥)。 因此,软件和硬件之间的通信是通过内核完成的。
首先说明一下什么叫体系结构:
计算机体系结构是程序员所看到的计算机的属性,即计算机的逻辑结构和功能特征,包括其各个硬部件和软部件之间的相互关系。对计算机系统设计者,计算机体系结构是指研究计算机的基本设计思想和由此产生的逻辑结构;对程序设计者是指对系统的功能描述(如指令集、编制方式等) 。
然后先介绍一下现有的主要体系结构:大内核和微内核。
从体系结构的概念我们可以知道大内核和微内核是通过功能特征进行划分的逻辑结构。之前我们提高操作系统在核心态为应用程序提供多种公共服务,例如操作系统的几个重要的管理功能:进程管理/存储器管理/文件管理/设备管理,又比如中断操作/时钟管理等。
为什么提出不同的体系结构?
这里通过一张图来解释如何通过功能划分区别大内核和微内核:
1⃣️大内核:把第二/三层放入内核运行。
整体式内核首先仅包含一个模块,而该模块负责内核所执行的所有功能。 由于所有功能都存在于同一模块中,因此提高了OS的性能(不需要频繁的切换用户态和内核态),但这也导致了严重的缺陷,例如内核的尺寸过大,可靠性非常低,因为即使内核的单个功能失败,这也会导致由于相同的原因,整个内核程序都会失败,并且维护不善。 因此,为了提高系统性能,在Monolithic内核中采用了模块化方法,其中每个功能都存在于内核空间内的不同模块中。 因此,对于修复任何错误或出现故障的情况,修复后仅卸载和加载该特定模块。
2⃣️微内核:只第三层放入内核运行。
在这种内核架构中,设备驱动管理、协议栈管理、文件系统管理和图形控制等基本用户服务都在用户空间中,其余的内存管理、进程管理等功能在内核空间中。 因此,每当系统需要内核空间中存在的服务时,操作系统就会切换到内核模式,而对于用户级服务,它会切换到用户模式。 这种类型的内核架构减少了内核的大小,但执行进程和提供其他服务的速度比单片内核慢得多(需要频繁变态)。
总结:
优缺点:
大内核:
缺点:高性能。 缺点:内核代码大,结果混乱,难以维护。
微内核:
优点:内核功能少,结构清晰,方便管理,更加稳定。 缺点:性能低。
当采用微内核把进程管理/存储管理/设备管理均放在用户态执行时,依旧需要内核态的支持才能实现,因此会出现频繁状态的转换,导致系统开销增加,性能降低。
大内核系统将操作系统的主要内容模块都作为一个紧密联系的整体运行在核心态,从而为应用提供高性能的系统服务。因为各管理模块之间共享信息,能有效 利用相互之间的有效特性, 所以具有无可比拟的性能优势。
但随着体系结构和应用需求的不断发展,需要操作系统提供的服务越来越多,而且接口形式越来越复杂,操作系统的设计模式也急剧增长,操作系统也面临着“软件危机”困境。为此,操作系统设计人员试图按照复杂性、时间常数、抽象级别等因素。将 操作系统内核分为基本进程管理、 虚存、I/O与设备管理、IPC、文件系统等几个层次,继而定义层次之间的服务结构,提高操作系统内核设计上的模块化。但是由于层次之间的 交互关系错综复杂,定义清晰的层次接口非常困难,复杂的交互关系也使得层次之间的界限极其模糊。
为解决操作系统的内核代码难以维护的问题,于是提高了微内核的体系结构。它将内核中最基本的功能(如进程管理)保留在内核,而将那些不需要在核心态执行的程序移到用户态执行着(但是要注意,程序是到用户态执行但是,依旧要陷入内核态进行操作系统服务的请求,因此不管是大内核还是微内核操作系统都具有管理功能,要想使用这些管理功能必须陷入内核态),从而降低了内核的设计复杂性。而那些移除内核的操作系统代码根据分层的原则被划分为若干服务程序,他们的执行相互独立,交互则都借助于微内核进行通信。
微内核有效地分离了内核与服务、服务与服务,使它们之间的接口更加清晰,维护的代价大大降低,各部分可以独立地优化和演进,从而保证了操作系统的可靠性。
微内核结构的最大问题是性能问题,因为需要频繁地在核心态和用户态之间进行切换,操作系统的执行开销偏大,因此有的操作系统将那些频繁使用的系统服务又移回了内核, 从而保证系统性能。但是有相当多的实验数据表明,体系结构不是引起性能下降的主要因素,体系结构带来的性能提升足以弥补切换开销带来的缺陷。为了减少切换开销,也有人提出将系统服务作为运行库链接到用户程序的一种解决方案,这样的体系结构称为库操作系统。
这里再强调一下系统调用的概念及运行过程:
linux内核中设置了一组用于实现系统功能的子程序,称为系统调用。系统调用和普通库函数调用非常相似,只是系统调用由操作系统核心提供,运行于核心态,而普通的函数调用由函数库或用户自己提供,运行于用户态。
一般进程是不能访问内核的。它不能访问内核所占内存空间也不能调用内核函数。CPU硬件决定了这些(这就是为什么它被称作”保护模式”)。为了和用户空间上运行的进程进行交互,内核提供了一组接口。透过该接口,应用程序可以访问硬件设备和其他操作系统资源。这组接口在应用程序和内核之间扮演了使者的角色,应用程序发送各种请求,而内核负责满足这些请求(或者让应用程序暂时搁置)。实际上提供这组接口主要是为了保证系统稳定可靠,避免应用程序肆意妄行,惹出大麻烦。
操作系统为用户态进程与硬件设备进行交互提供了一组接口——系统调用:
1.把用户从底层的硬件编程中解放出来
2.极大的提高了系统的安全性
3.使用户程序具有可移植性
系统调用是用户态进入内核态的唯一入口,而中断是用户态进入内核态的唯一途径。
用户空间的程序无法直接执行内核代码,它们不能直接调用内核空间中的函数,因为内核驻留在受保护的地址空间上。如果进程可以直接在内核的地址空间上读写的话,系统安全就会失去控制。所以,应用程序应该以某种方式通知系统,告诉内核自己需要执行一个系统调用,希望系统切换到内核态,这样内核就可以代表应用程序来执行该系统调用了。
通知内核的机制是靠软件中断实现的。首先,用户程序为系统调用设置参数。其中一个参数是系统调用编号。参数设置完成后,程序执行“系统调用”指令。x86系统上的软中断由int产生。这个指令会导致一个异常:产生一个事件,这个事件会致使处理器切换到内核态并跳转到一个新的地址,并开始执行那里的异常处理程序。此时的异常处理程序实际上就是系统调用处理程序。它与硬件体系结构紧密相关。