从这部分开始,我们将主要以Linux为基础,为读者介绍操作系统的部分基础设计逻辑。通过这部分内容,读者将看到一个不同的操作系统,一个更加形象,更加生动的操作系统。在前面几部分,我们尝试从软件需要的逻辑角度,模型化了计算机的各个硬件模块,并最终进行了整合。那些模型图及其传递的抽象思想将在这部分以及后续部分频繁的出现。可以说,之前是学,到这部分则是用了。
不论从任何角度来看,操作系统都是一个庞大的软件,它完成了对硬件的封装,简化了对资源的使用,提高了设备效率,丰富了产品应用。可以说,没有操作系统,计算机基本就是一堆废铁;没有好的操作系统,计算机就只能在实验室里待着,只能是少部分“专家”的专属品,自然也不会这么普及了。下图是这种封装的一个示意图。计算机从最底层硬件到最上层应用,最大的特点就是层层封装。
操作系统虽然复杂,但是经过这么多年的发展,还是基本形成了一套概念与理论。特别是在操作系统应该都包含什么内容方面,基本形成了统一的认识。从现在的角度来看,操作系统应包括进程管理、内存管理、文件系统、网络栈、设备管理即驱动管理、上层接口等几个大的模块。我们据此可以将上图进一步细化为下图
当然,随着时代的发展,操作系统的概念还是大大的扩展了,出现了针对特定领域或场景的大操作系统概念,比如分布式操作系统,云计算操作系统等。这里,我们还是围绕传统操作系统的特性展开讨论。
在正式开始各个模块的介绍之前,我们通过几张图来对Linux操作系统进行一个直观的认识。首先,是一幅逻辑框图,分层展示,如下图(图片来自网络)。
从另一个角度来看,包含了动态的可插拔模块机制(图片来自网络):
上面这两幅图都是粗略的大块。再来看一幅添加了接口关联的图。(图片来自:http://www.makelinux.net/kernel/diagram)
再进一步的细化,如下图所示:
(图片来自:http://www.makelinux.net/kernel_map,国内版地址:https://linuxstory.org/wp-content/uploads/2016/01/linux-kernel-map-linux_story.jpg)
肉眼可见的复杂度陡然提升。
不知有没有读者会去想,操作系统这么庞大复杂,写这样一个系统,得要多少代码量?还别说,有人就做过这样的统计。从代码行数上来计算,现代操作系统的代码行数都是在百万行级别以上,比如,Linux2.6就在500万以上。那进一步,这些代码量,分配到各个模块上,比例是怎样的?得益于Linux的开源特性,也还真有人做过类似的分析,如下图这种叫做treemap的可视化图形:
(图片来自:http://www.cs.umd.edu/hcil/millionvis/Treemap_Visualization_of_the_Linux_Kernel_2_5_33.html)
上图看着是不是很有意思呢?也许所有人都没有想到,平台(Arch)和驱动(Driver)模块相关的代码量是最大的。相比而言,进程调度代码只占很少一部分,但是实际上许多操作系统教材中这部分却是占用大量篇幅来介绍的。这个结果也值得我们仔细思考,想想它背后的原因。(关于内核代码量,感兴趣的读者可以参考该连接,关于5.9版本的代码量统计:https://www.cnbeta.com/articles/tech/1039385.htm)
到此,不管怎样,对于操作系统,大家应该是有了一个直观的印象。后面就针对操作系统的具体专题展开介绍。后面介绍完操作系统的功能后,希望能够从下面两个角度,对操作系统有一定的认知:
角度1:对操作系统的代码区和数据结构有一个形象的认识,包括任务管理结构、内存管理结构、文件系统管理结构、中断向量表等等。也算是有了一个操作系统的简单模型。
角度2:从开发应用程序的角度来看操作系统应该包含什么、提供什么、完成什么。