操作系统实践之路(二、总体架构设计)

回顾:操作系统实践之路(一、环境配置)
前言

​ 之前介绍了一个极简的操作系统——Hello OS,并且成功运行,但是其实没有任何实际的功能,仅仅只是能够打印一句话而已。而想要实现一个正常功能的操作系统内核,其内部是比较复杂的,所以需要在开发之前对内核进行设计,绘制出其蓝图,再去组织内核中的资源,并且对比当下成熟的架构,最后设计出我们想要的内核架构。

一、资源

​ 从抽象的角度来看,内核就是计算机资源的管理者。而计算机中的资源可以大致分为两类:一种是硬件资源,一种是软件资源。

1.1硬件资源

  1. 总线,负责连接各种其它设备,是其它设备工作的基础。
  2. CPU,即中央处理器,负责执行程序和处理数据运算。
  3. 内存,负责储存运行时的代码和数据。
  4. 硬盘,负责长久储存用户文件数据。
  5. 网卡,负责计算机与计算机之间的通信。
  6. 显卡,负责显示工作。
  7. 各种 I/O 设备,如显示器,打印机,键盘,鼠标等。

下面是一副经典的计算机内部结构图

在这里插入图片描述

1.2软件资源

​ 计算机中的软件资源,则可表示为计算机中的各种形式的数据。如各种文件、软件程序等。

内核作为硬件资源和软件资源的管理者,其内部组成在逻辑上大致如下:

1.管理 CPU,由于 CPU 是执行程序的,而内核把运行时的程序抽象成进程,所以又称为进程管理。

2.管理内存,由于程序和数据都要占用内存,内存是非常宝贵的资源,所以内核要非常小心地分配、释放内存。

3.管理硬盘,而硬盘主要存放用户数据,而内核把用户数据抽象成文件,即管理文件,文件需要合理地组织,方便用户查找和读写,所以形成了文件系统。

4.管理显卡,负责显示信息,而现在操作系统都是支持 GUI(图形用户接口)的,管理显卡自然而然地就成了内核中的图形系统。

5.管理网卡,网卡主要完成网络通信,网络通信需要各种通信协议,最后在内核中就形成了网络协议栈,又称网络组件。

6.管理各种 I/O 设备,我们经常把键盘、鼠标、打印机、显示器等统称为 I/O(输入输出)设备,在内核中抽象成 I/O 管理器。

​ 内核除了这些必要组件之外,根据功能不同还有安全组件等,最值得一提的是,各种计算机硬件的性能不同,硬件型号不同,硬件种类不同,硬件厂商不同,内核要想管理和控制这些硬件就要编写对应的代码,通常这样的代码我们称之为驱动程序

​ 以上我们已经大致知道了内核之中有哪些组件,但是另一个问题又出现了,即如何组织这些组件,让系统更加稳定和高效,这就需要我们从现有的一些经典内核结构里找灵感了。

二、经典内核结构

2.1宏内核结构

宏内核结构是最简单适用,也是最早的一种内核结构。

​ 宏内核的结构思想就是把进程管理,内存管理,设备管理,文件系统管理,图形系统管理以及其他功能模块的代码经过编译,最后链接在一起,形成一个大的可执行程序。它就像一台汽车发动机一般,将各种零部件紧密地组装在一起,共同高效完成任务。

​ 这个大的可执行程序可以向用户应用软件提供一些API函数接口,并且会在CPU的特权模式下运行,这就是宏内核模式

宏内核结构如下图所示:

在这里插入图片描述

​ 尽管图中是一层一层排序,但这并不代表他们有层次关系,仅仅是表示它们链接在一起。

​ 宏内核提供内存分配功能的具体过程

1.应用程序调用内存分配的 API(应用程序接口)函数。

2.处理器切换到特权模式,开始运行内核代码。

3.内核里的内存管理代码按照特定的算法,分配一块内存。

4.把分配的内存块的首地址,返回给内存分配的 API 函数。

5.内存分配的 API 函数返回,处理器开始运行用户模式下的应用程序,应用程序就得到了一块内存的首地址,并且可以使用这块内存了。

优点:性能好,组件之间可以互相调用,性能极高。

缺点:没有模块化,没有扩展性,没有移植性,高度耦合,一旦其中一个组件有漏洞,可能会造成整个程序崩溃。

宏内核强调组织间的相互关联性,就像是一种命令由上到下的一个传递过程。

2.2微内核

微内核架构正好与宏内核架构相反,它提倡内核功能尽可能少:仅仅只有进程调度、处理中断、内存空间映射、进程间通信等功能。

微内核把进程管理、内存管理、设备管理、文件管理等服务功能做成一个个服务进程,与用户应用进程一样

微内核定义了进程间通信的机制——消息。用户应用程序请求服务,向内核发送消息,内核再把这条消息传给相关服务进程,然后该服务进程完成相关的任务。服务进程就是一直循环处理其他进程的消息,完成相应服务。就像在饭店吃饭一样, 顾客点单,服务员把顾客点的单传到后厨,厨师再根据单上的内容做菜。

微内核结构如下图所示:

在这里插入图片描述

​ 微内核提供内存分配功能的服务过程:

1、应用程序发送内存分配的消息给内存,但是这个发送消息的函数是内核提供的(微内核提供的API很少),首先这个应用程序把消息传给内核

2、处理器切换到特权模式,运行内核代码

3、微内核停止当前进程,根据发送来的消息中的数据,确定发给谁,分配内存的消息就是发给内存管理服务进程

4、内存管理服务进程收到内核来的消息,分配一块内存

5、内存管理服务进程,分配完成后,发送消息给微内核,并返回分配内存的首地址,然后继续等待下一条消息

6、微内核把内存管理服务进程传来的包含内存块首地址的消息再返回给发送内存分配消息的应用程序

7、处理器开始运行用户模式下的应用程序,应用程序得到一块内存的首地址,可以使用这块内存了

优点:系统结构清晰,有良好的移植性,代码量少,有相当好的伸缩性、拓展性

缺点:内核处理一条消息,走的路比宏内核多了好多,一来一去的消息就会造成很大的开销,性能也不如宏内核好。服务进程切换开销大,系统性能大打折扣。

微内核强调的是独立,相互调用性,感觉就像部门与部门之间的合作关系。

2.3分离硬件

​ 分离硬件的相关性,就是要把操作硬件和处理硬件功能差异的代码抽离出来,形成一个独立的软件抽象层,对外提供相应的接口,方便上层开发。其运用了分层和抽象的思想。

​ 今天如此庞杂的计算机,其实也是一层一层地构建起来的,从硬件层到操作系统层再到应用软件层这样构建。分层的主要目的和好处在于屏蔽底层细节,使上层开发更加简单

​ 如果把所有硬件平台相关的代码,都抽离出来,放在一个独立硬件相关层中实现并且定义好相关的调用接口,再在这个层之上开发内核的其它功能代码,就会方便得多,结构也会清晰很多。操作系统的移植性也会大大增强,移植到不同的硬件平台时,就构造开发一个与之对应的硬件相关层。这就是分离硬件相关性的好处。

三、内核总体设计

虽然前面的内容对于操作系统设计这个领域还不够,但对于我们自己从0开始的操作系统内核已经足够了。

同样运用分层和抽象,将我们的操作系统分为三个大层:内核接口层、内核功能层、内核硬件层。

3.1内核接口层

内核接口层,定义了一系列的接口。

主要有两点内容:

1.定义了一套 UNIX 接口的子集。出于学习和研究的目的选择使用UNIX接口的子集,其优点是接口少,只有几个,并且这几个接口能大致定义出操作系统的功能

2.这套接口的代码,就是检查其参数是否合法,如果参数有问题就返回相关的错误,没有就接着调用下层完成功能的核心代码。

3.2内核功能层

内核功能层,主要完成各种实际功能。这些功能按照其类别可以分成各种模块,内核功能层的模块如下:

1.进程管理,主要是实现进程的创建、销毁、调度进程。

2.内存管理,在内核功能层中只有内存池管理,分两种内存池:页面内存池和任意大小的内存池。

3.中断管理,就是把一个中断回调函数安插到相关的数据结构中,一旦发生相关的中断就会调用这个函数。

4.设备管理,要用一系列的数据结构表示驱动程序模块、驱动程序本身、驱动程序创建的设备,最后把它们组织在一起,还要实现创建设备、销毁设备、访问设备的代码,这些代码最终会调用设备驱动程序,达到操作设备的目的。

3.3内核硬件层

内核硬件层,主要包括一个具体硬件平台相关的代码,如下:

1.初始化,就是加载到内存最先需要运行的代码,如初始化CPU,内寸、中断的控制、内核用于管理的数据结构等

2.CPU控制,提供 CPU 模式设定,开关中断,读写寄存器等

3.中断处理,保存中断上下文,调用中断回调函数,操作中断控制器等

4.物理内存管理,分配释放内存,内存空间映射,操作MMU,Cache等

5.其他功能,有些硬件平台有特殊功能,单独处理

API 接口以下的为内核空间,这才是设计、开发内核的重点:

在这里插入图片描述

​ 从上述文字和图示,可以发现,我们的操作系统内核没有任何设备驱动程序,甚至没有文件系统和网络组件,内核所实现的功能很少。这吸取了微内核的优势,内核小出问题的可能性就少,扩展性就越强。同时,我们把文件系统、网络组件、其它功能组件作为虚拟设备交由设备管理,比如需要文件系统时就写一个文件系统虚拟设备的驱动,完成文件系统的功能,需要网络时就开发一个网络虚拟设备的驱动,完成网络功能。这些驱动一旦被装载,就是内核的一部分了,并不是像微内核一样作为服务进程运行。这又吸取了宏内核的优势,代码高度耦合,性能强劲。

​ 这样的内核架构既不是宏内核架构也不是微内核架构,而是这两种架构综合的结果,可以说是混合内核架构……

​ 总体来说,我们需要取得微内核的优点:结构简单,调用清晰,扩展方便。但是不想为此付出太多的性能成本,这样不得不对微内核做一些功能上限制,采取宏内核的组织方式。设计上是微内核的,实现上是宏内核的,权衡了结构清晰和模块间的调用性能。所以,性能强,并且是可拓展,吸收了微内核和宏内核各自的优点。

四、业界成熟内核架构

​ 以下介绍三大内核架构——Linux、Windows NT和 Darwin。

4.1 Linux 内核

​ Linux,全称 GNU/Linux,是一套免费使用和自由传播的操作系统,支持类 UNIX、POSIX 标准接口,也支持多用户、多进程、多线程,可以在多 CPU 的机器上运行。Linux 系统性能稳定且开源。Linux 的基本思想是一切都是文件:每个文件都有确定的用途,包括用户数据、命令、配置参数、硬件设备等对于操作系统内核而言,都被视为各种类型的文件。Linux内核采用传统的内核结构,也称为宏内核架构。

在这里插入图片描述

4.2 Darwin-XNU 内核

​ Darwin 是由苹果公司在 2000 年开发的一个开放源代码的操作系统。

Darwin 的架构:

在这里插入图片描述

​ 它有两个内核层——Mach 层与 BSD 层。应用会通过用户层的框架和库来请求 Darwin 系统的服务,即调用 Darwin 系统 API。在调用 Darwin 系统 API 时,会传入一个 API 号码,用这个号码去索引 Mach 陷入中断服务表中的函数。此时,API 号码如果小于 0,则表明请求的是 Mach 内核的服务,API 号码如果大于 0,则表明请求的是 BSD 内核的服务,它提供一整套标准的 POSIX 接口。就这样,Mach 和 BSD 就同时存在了。Darwin-XNU 内核层也成为了多内核架构的代表。

4.3 Windows NT 内核

​ Windows NT 是微软于 1993 年推出的面向工作站、网络服务器和大型计算机的网络操作系统,也可做 PC 操作系统。它是一款全新从零开始开发的新操作系统,并应用了现代硬件的所有特性,“NT”所指的便是“新技术”(New Technology)。

Windows NT 内核:

在这里插入图片描述

​ 微软自己在 HAL 层上是定义了一个小内核,小内核之下是硬件抽象层 HAL,这个 HAL 存在的好处是:不同的硬件平台只要提供对应的 HAL 就可以移植系统了。小内核之上是各种内核组件,微软称之为内核执行体,它们完成进程、内存、配置、I/O 文件缓存、电源与即插即用、安全等相关的服务。NT 内核中各层次分明,各个执行体互相独立,遵循“高内聚、低偶合”的设计标准。

参考资料

以上内容是我学习彭东老师的《操作系统实战45讲》后所进行的一个笔记记录,如有错误,还请各位大佬多多指教。

我主要参考了以下资料,十分感谢:

操作系统实战45讲——彭东老师

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值