You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
15 KiB
Markdown

2 years ago
# 04 | 震撼的Linux全景图业界成熟的内核架构长什么样
你好我是LMOS。
什么?你想成为计算机黑客?
梦想坐在计算机前敲敲键盘,银行账号里的数字就会自己往上涨。拜托,估计明天你就该被警察逮捕了。真正的黑客是对计算机技术有近乎极致的追求,而不是干坏事。
下面我就带你认识这样一个计算机黑客看看他是怎样创造出影响世界的Linux然后进一步了解一下Linux的内部结构。
同时我也会带你看看Windows NT和Darwin的内部结构三者形成对比你能更好地了解它们之间的差异和共同点这对我们后面写操作系统会很有帮助。
## 关于Linus
Linus Benedict Torvalds这个名字很长下面简称Linus他1969年12月28日出生在芬兰的赫尔辛基市并不是美国人。Linus在赫尔辛基大学学的就是计算机妻子还是空手道高手一个“码林高手”和一个“武林高手”真的是绝配啊。
Linus在小时候就对各种事情充满好奇这点非常具有黑客精神后来有了自己的计算机更是痴迷其中开始自己控制计算机做一些事情并深挖其背后的原理。就是这种黑客精神促使他后来写出了颠覆世界的软件——Linux也因此登上了美国《时代》周刊。
你是否对很多垃圾软件感到愤慨但自己又无法改变。Linus就不一样他为了方便访问大学服务器中的资源 ,而在自己的机器上写了一个文件系统和硬盘驱动,这样就可以把自己需要的资源下载到自己的机器中。
再后来这成为了Linux的第一个版本。看看牛人之所以为牛人就是敢于对现有的规则说不并勇于改变。
如果仅仅如此那么也不会有后来的Linux内核。Linus随后做了一个重要决定他把这款操作系统雏形开源并加入到自由软件运动以GPL协议授权允许用户自由复制或者改动程序代码但用户必须公开自己的修改并传播。
无疑正是Linus的这一重要决定使得Linux和他自己名声大振。短短几年时间就已经聚集了成千上万的狂热分子大家不计得失的为Linux添砖加瓦很多程序员更是对Linus像神明一样顶礼膜拜。
## Linux内核
好了回到正题回到Linux。Linus也不是什么神明现有的Linux99.9%的代码都不是Linus所写而且他的代码也不一定比你我的代码写得更好。
Linux全称GNU/Linux是一套免费使用和自由传播的操作系统支持类UNIX、POSIX标准接口也支持多用户、多进程、多线程可以在多CPU的机器上运行。由于互联网的发展Linux吸引了来自全世界各地软件爱好者、科技公司的支持它已经从大型机到服务器蔓延至个人电脑、嵌入式系统等领域。
Linux系统性能稳定且开源。在很多公司企业网络中被当作服务器来使用这是Linux的一大亮点也是它得以壮大的关键。
Linux的基本思想是一切都是文件每个文件都有确定的用途包括用户数据、命令、配置参数、硬件设备等对于操作系统内核而言都被视为各种类型的文件。Linux支持多用户各个用户对于自己的文件有自己特殊的权利保证了各用户之间互不影响。多任务则是现代操作系统最重要的一个特点Linux可以使多个程序同时并独立地运行。
Linux发展到今天不是哪一个人能做到的更不是一群计算机黑客能做到的而是由很多世界级的顶尖科技公司联合开发如IBM、甲骨文、红帽、英特尔、微软它们开发Linux并向Linux社区提供补丁使Linux工作在它们的服务器上向客户出售业务服务。
Linux发展到今天其代码量近2000万行可以用浩如烟海来形容没人能在短时间内弄清楚。但是你也不用害怕我们可以先看看Linux内部的全景图从全局了解一下Linux的内部结构如下图。
![](https://static001.geekbang.org/resource/image/92/cb/92ec3d008c77bb66a148772d3c5ea9cb.png?wh=2160*1620 "Linux内部的全景图")
啊哈是不是感觉壮观之后一阵头晕目眩头晕目眩就对了因为Linux太大了别怕下面我们来分解一下。但这里我要先解释一下上图仍然不足于描述Linux的全部只是展示了重要且显而易见的部分。
上图中大致分为**五大重要组件**,每个组件又分成许多模块从上到下贯穿各个层次,每个模块中有重要的函数和数据结构。具体每个模块的主要功能,我都给你列在了文稿里,你可以详细看看后面这张图。
![](https://static001.geekbang.org/resource/image/97/c9/97e7e66f9dcbddb1294ef9b7552fbac9.jpg?wh=3046x1502)
不要着急不要心慌因为现在我们不需要搞清楚这些Linux模块的全部实现细节只要在心里默念Linux的模块真多啊大概有五大组件有好几十个模块每个模块主要完成什么功能就行了。
是不是松了口气先定定神然后我们就能发现Linux这么多模块挤在一起之间的通信主要是函数调用而且函数间的调用没有一定的层次关系更加没有左右边界的限定。函数的调用路径是纵横交错的从图中的线条可以得到印证。
继续深入思考你就会发现,这些纵横交错的路径上有一个函数出现了问题,就麻烦大了,它会波及到全部组件,导致整个系统崩溃。当然调试解决这个问题,也是相当困难的。同样,模块之间没有隔离,安全隐患也是巨大的。
当然,这种结构不是一无是处,它的性能极高,而性能是衡量操作系统的一个重要指标。这种结构就是传统的内核结构,也称为**宏内核架构**。
想要评判一个产品好不好最直接的方法就是用相似的产品对比。你说Linux很好但是什么为好呢我说Linux很差它又差在什么地方呢
下面我们就拿出Windows和macOS进行对比注意我们只是对比它们的内核架构。
## Darwin-XNU内核
我们先来看看DarwinDarwin是由苹果公司在2000年开发的一个开放源代码的操作系统。
一个经久不衰的公司必然有自己的核心竞争力也许是商业策略也许是技术产品又或是这两者的结合。而作为苹果公司各种产品和强大的应用生态系统的支撑者——Darwin更是公司核心竞争力中的核心。
苹果公司有台式计算机、笔记本、平板、手机台式计算机、笔记本使用了macOS操作系统平板和手机则使用了iOS操作系统。Darwin作为macOS与iOS操作系统的核心从技术实现角度说它必然要支持PowerPC、x86、ARM架构的处理器。
Darwin 使用了一种微内核Mach和相应的固件来支持不同的处理器平台并提供操作系统原始的基础服务上层的功能性系统服务和工具则是整合了BSD系统所提供的。苹果公司还为其开发了大量的库、框架和服务不过它们都工作在用户态且闭源。
下面我们先从整体看一下Darwin的架构。
![](https://static001.geekbang.org/resource/image/5e/8d/5e9bd6dd86fba5482fab14b6b292aa8d.jpg?wh=4462*4410 "Darwin架构图")
什么两套内核惊不惊喜由于我们是研究Darwin内核所以上图中我们只需要关注内核-用户转换层以下的部分即可。显然它有两个内核层——**Mach层与BSD层**。
Mach内核是卡耐基梅隆大学开发的经典微内核意在提供最基本的操作系统服务从而达到高性能、安全、可扩展的目的而BSD则是伯克利大学开发的类UNIX操作系统提供一整套操作系统服务。
那为什么两套内核会同时存在呢?
MAC OS X2011年之前的称呼的发展经过了不同时期随着时代的进步产品功能需求增加单纯的Mach之上实现出现了性能瓶颈但是为了兼容之前为Mach开发的应用和设备驱动就保留了Mach内核同时加入了BSD内核。
Mach内核仍然提供十分简单的进程、线程、IPC通信、虚拟内存设备驱动相关的功能服务BSD则提供强大的安全特性完善的网络服务各种文件系统的支持同时对Mach的进程、线程、IPC、虚拟内核组件进行细化、扩展延伸。
那么应用如何使用Darwin系统的服务呢应用会通过用户层的框架和库来请求Darwin系统的服务即调用Darwin系统API。
在调用Darwin系统API时会传入一个API号码用这个号码去索引Mach陷入中断服务表中的函数。此时API号码如果小于0则表明请求的是Mach内核的服务API号码如果大于0则表明请求的是BSD内核的服务它提供一整套标准的POSIX接口。
就这样Mach和BSD就同时存在了。
Mach中还有一个重要的组件Libkern它是一个库提供了很多底层的操作函数同时支持C++运行环境。
依赖这个库的还有IOKitIOKit管理所有的设备驱动和内核功能扩展模块。驱动程序开发人员则可以使用C++面向对象的方式开发驱动这个方式很优雅你完全可以找一个成熟的驱动程序作为父类继承它要特别实现某个功能就重载其中的函数也可以同时继承其它驱动程序这大大节省了内存也大大降低了出现BUG的可能。
如果你要详细了解Darwin内核的话可以自行阅读[相应的代码](https://github.com/apple/darwin-xnu)。而在这里,你只要从全局认识一下它的结构就行了。
## Windows NT内核
接下来我们再看下 NT 内核。现代Windows的内核就是NT我们不妨先看看NT的历史。
如果你是90后大概没有接触过MS-DOS它的交互方式是你在键盘上输入相应的功能命令它完成相应的功能后给用户返回相应的操作信息没有图形界面。
在MS-DOS内核的实现上也没有应用现代硬件的保护机制这导致后来微软基于它开发的图形界面的操作系统如Windows 3.1、Windows95/98/ME极其不稳定且容易死机。
加上类UNIX操作系统在互联网领域大行其道所以微软急需一款全新的操作系统来与之竞争。所以Windows NT诞生了。
Windows NT是微软于1993年推出的面向工作站、网络服务器和大型计算机的网络操作系统也可做PC操作系统。它是一款全新从零开始开发的新操作系统并应用了现代硬件的所有特性“NT”所指的便是“新技术”New Technology
而普通用户第一次接触基于NT内核的Windows是Windows 2000一开始用户其实是不愿意接受的因为Windows 2000对用户的硬件和应用存在兼容性问题。
随着硬件厂商和应用厂商对程序的升级这个兼容性问题被缓解了加之Windows 2000的高性能、高稳定性、高安全性用户很快便接受了这个操作系统。这可以从Windows 2000的迭代者Windows XP的巨大成功得到验证。
现在NT内核在设计上层次非常清晰明了各组件之间界限耦合程度很低。下面我们就来看看NT内核架构图了解一下NT内核是如何“庄严宏伟”。如下图
![](https://static001.geekbang.org/resource/image/c5/c9/c547b6252736375fcdb1456e6dfaa3c9.jpg?wh=4268*4905 "NT内核架构图")
这样看NT内核架构是不是就清晰了很多但这并不是我画图画得清晰事实上的NT确实如此。
这里我要提示一下,上图中我们只关注内核模式下的东西,也就是传统意义上的内核。
当然微软自己在HAL层上是定义了一个小内核小内核之下是硬件抽象层HAL这个HAL存在的好处是不同的硬件平台只要提供对应的HAL就可以移植系统了。小内核之上是各种内核组件微软称之为内核执行体它们完成进程、内存、配置、I/O文件缓存、电源与即插即用、安全等相关的服务。
每个执行体互相独立只对外提供相应的接口其它执行体要通过内核模式可调用接口和其它执行体通信或者请求其完成相应的功能服务。所有的设备驱动和文件系统都由I/O管理器统一管理驱动程序可以堆叠形成I/O驱动栈功能请求被封装成I/O包在栈中一层层流动处理。Windows引以为傲的图形子系统也在内核中。
显而易见NT内核中各层次分明各个执行体互相独立这种“高内聚、低偶合”的特性正是检验一个软件工程是否优秀的重要标准。而这些你都可以通过微软公开的WRK代码得到佐证如果你觉得WRK代码量太少也可以看一看[REACT OS](https://reactos.org/)这个号称“开源版”的NT。
## 重点回顾
到这里我们了解了Linux、Darwin-XNU和Windows的发展历史也清楚了它们内部的组件和结构并对它们的架构进行了对比对比后我们发现**Linux性能良好结构异常复杂不利于问题的排查和功能的扩展而Darwin-XNU和Windows结构良好层面分明利于功能扩展不容易产生问题且性能稳定。**
下面我们来回顾下这节课的重点。
首先我们从一名计算机黑客切入简单介绍了一下Linus他由于沉迷于技术对不好的规则敢于挑战而写出了Linux雏形并且利用了GNU开源软件的精神推动了Linux后来的发展这样的精神很值得我们学习。
然后我们探讨了Linux内核架构大致搞清楚了Linux内核中的各种组件它们是系统、进程、内存、储存、网络。其中每个组件都是从接口到硬件经过了几个层次组件与组件之间的层次互联调用。这些组件组合在一起其调用关系形成了一个巨大的网状结构。因此Linux也成了宏内核的代表。
为了有所对比我们研究了苹果的Darwin-XNU内核结构发现其分层更细固件层、Mach层屏蔽了硬件平台的细节向上层提供了最基础的服务。在Mach层之上的BSD层提供了更完善的服务它们是进程与线程、IPC通信、虚拟内存、安全、网络协议栈以及文件系统。通过Mach中断嵌入表可以让应用自己决定使用Mach层服务还是使用BSD层的服务因此Darwin-XNU拥有了两套内核Darwin-XNU内核层也成为了多内核架构的代表。
最后我们研究了迄今为止最成功的商业操作系统——Windows它的内核是NT其结构清晰明了各组件完全遵循了软件工程**高内聚、低偶合**的设计标准。最下层是HAL硬件抽象HAL层是为了适配各种不同的硬件平台在HAL层之上就是微软定义的小内核你可以理解成是NT内核的内核在这个小内核之上就是各种执行体了这些执行体提供了操作系统的进程、虚拟内存、文件数据缓存、安全、对象管理、配置等服务还有Windows的技术核心图形系统。
## 思考题
Windows NT内核属于哪种架构类型
很期待在留言区看到你的分享,也欢迎你把这节课分享给身边的同事、朋友。
我是LMOS让我们下节课见。