软件工程实践 Blog 2

软件工程实践 Blog2

2021SC@SDUSC


学习模块:计算机系统 —— 笔记 02
主要内容:储备系统原理的知识,自底向上的学习路线


003 内核结构与设计

从用户和应用程序的角度来看,内核之中有什么并不重要,能提供什么服务才是重要的,所以内核在用户和上层应用眼里,就像一个大黑盒,至于黑盒里面有什么,怎么实现的,就不用管了。

从抽象角度来看,内核就是计算机资源的管理者,当然管理资源是为了让应用使用资源。既然内核是资源的管理者,我们先来看看计算机中有哪些资源,然后通过资源的归纳,就能推导出内核这个大黑盒中应该有什么。

计算机中资源大致可以分为两类资源,一种是硬件资源,一种是软件资源。
先来看看硬件资源有哪些,如下:

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

硬件架构而计算机中的软件资源,则可表示为计算机中的各种形式的数据。如各种文件、软件程序等。内核作为硬件资源和软件资源的管理者,其内部组成在逻辑上大致如下:

  • 管理 CPU,由于 CPU 是执行程序的,而内核把运行时的程序抽象成进程,所以又称为进程管理。
  • 管理内存,由于程序和数据都要占用内存,内存是非常宝贵的资源,所以内核要非常小心地分配、释放内存。
  • 管理硬盘,而硬盘主要存放用户数据,而内核把用户数据抽象成文件,即管理文件,文件需要合理地组织,方便用户查找和读写,所以形成了文件系统
  • 管理显卡,负责显示信息,而现在操作系统都是支持 GUI(图形用户接口)的,管理显卡自然而然地就成了内核中的图形系统。
  • 管理网卡,网卡主要完成网络通信,网络通信需要各种通信协议,最后在内核中就形成了网络协议栈,又称网络组件。
  • 管理各种 I/O 设备,我们经常把键盘、鼠标、打印机、显示器等统称为 I/O(输入输出)设备,在内核中抽象成 I/O 管理器。

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

经典内核结构

1. 宏内核
2. 微内核	
宏内核有极致的性能,微内核有极致的可移植性、可扩展性。
宏内核

宏内核就是把以上诸如管理进程的代码、管理内存的代码、管理各种 I/O 设备的代码、文件系统的代码、图形系统代码以及其它功能模块的代码,把这些所有的代码经过编译,最后链接在一起,形成一个大的可执行程序

这个大程序里有实现支持这些功能的所有代码,向用户应用软件提供一些接口,这些接口就是常说的系统 API 函数。而这个大程序会在处理器的特权模式下运行,这个模式通常被称为宏内核模式

结构如下图所示:
宏内核结构
注意:尽管图中一层一层的,这并不是它们有层次关系,仅仅表示它们链接在一起。

下面给出一个宏内核的实例过程:

  1. 应用程序调用内存分配的 API(应用程序接口)函数。
  2. 处理器切换到特权模式,开始运行内核代码。
  3. 内核里的内存管理代码按照特定的算法,分配一块内存。
  4. 把分配的内存块的首地址,返回给内存分配的 API 函数。
  5. 内存分配的 API 函数返回,处理器开始运行用户模式下的应用程序,应用程序就得到了一块内存的首地址,并且可以使用这块内存了。

上面这个过程和一个实际的操作系统中的运行过程,可能有差异,但大同小异。当然,系统 API 和应用程序之间可能还有库函数,也可能只是分配了一个虚拟地址空间,但是我们关注的只是这个过程。

优缺点
没有模块化,没有扩展性、没有移植性,高度耦合在一起,一旦其中一个组件有漏洞,内核中所有的组件可能都会出问题。
开发一个新的功能得重新编译、链接、安装内核。现在这种原始的宏内核结构已经没有人用了。
这种宏内核唯一的优点是性能很好,因为在内核中,这些组件可以互相调用,性能极高。


微内核

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

这样的内核是不能完成什么实际功能的,开发者们把实际的进程管理、内存管理、设备管理、文件管理等服务功能,做成一个个服务进程。
和用户应用进程一样,只是它们很特殊,宏内核提供的功能,在微内核架构里由这些服务进程专门负责完成

思考:如何等效地替代?一种设计方法,进行切分或功能分类,使用特殊进程调用微内核来等效替代宏内核的功能。

微内核定义了一种良好的进程间通信的机制——消息。应用程序要请求相关服务,就向微内核发送一条与此服务对应的消息,微内核再把这条消息转发给相关的服务进程,接着服务进程会完成相关的服务。服务进程的编程模型就是循环处理来自其它进程的消息,完成相关的服务功能。其结构如下所示:
微内核架构

思考:每当提出一种解决问题的新办法的时候,就会需要引入新的工具,在上面最好的体现就是消息这一概念的提出,进而对于微内核架构而言,对于各个进程间消息的处理成为主要命题之一。

对应地,我们探索一下微内核提供内存分配功能的服务过程:

  1. 应用程序发送内存分配的消息,这个发送消息的函数是微内核提供的,相当于系统 API,微内核的 API(应用程序接口)相当少,极端情况下仅需要两个,一个接收消息的 API 和一个发送消息的 API。
  2. 处理器切换到特权模式,开始运行内核代码。
  3. 微内核代码让当前进程停止运行,并根据消息包中的数据,确定消息发送给谁,分配内存的消息当然是发送给内存管理服务进程。
  4. 内存管理服务进程收到消息,分配一块内存。
  5. 内存管理服务进程,也会通过消息的形式返回分配内存块的地址给内核,然后继续等待下一条消息。
  6. 微内核把包含内存块地址的消息返回给发送内存分配消息的应用程序。
  7. 处理器开始运行用户模式下的应用程序,应用程序就得到了一块内存的首地址,并且可以使用这块内存了。

微内核的架构实现虽然不同,但是大致过程和上面一样。同样是分配内存,在微内核下拐了几个弯,一来一去的消息带来了非常大的开销,当然各个服务进程的切换开销也不小。这样系统性能就大打折扣。

优缺点:首先,系统结构相当清晰利于协作开发。其次,系统有良好的移植性,微内核代码量非常少,就算重写整个内核也不是难事。最后,微内核有相当好的伸缩性、扩展性,因为那些系统功能只是一个进程,可以随时拿掉一个服务进程以减少系统功能,或者增加几个服务进程以增强系统功能。微内核的代表作有 MACH、MINIX、L4 系统,这些系统都是微内核,但是它们不是商业级的系统,商业级的系统不采用微内核主要还是因为性能差。


分离硬件的相关性

我们会经常听说,Windows 内核有什么 HAL 层、Linux 内核有什么 arch 层。这些 xx 层就是 Windows 和 Linux 内核设计者,给他们的系统内核分的第一个层。

HAL层:Hardware Abstraction Layer 硬件抽象层
硬件抽象层技术最初是由Microsoft公司为确保WindowsNT的稳定性和兼容性而提出的。

针对过去Windows系列操作系统经常出现的系统死机或崩溃等现象,Microsoft总结发现,程序设计直接与硬件通信,是造成系统不稳定的主要原因。在得出这个结论的基础上,微软公司在WindowsNT上取消了对硬件的直接访问,首先提出了硬件抽象层(Hardware Abstraction Layer,简称HAL)的概念,硬件抽象层就是:“将硬件差别与操作系统其他层相隔离的一薄层软件,它是通过采用使多种不同硬件在操作系统的其他部分看来是同一种虚拟机的做法来实现的。“后来,这种HAL设计思路被一些嵌入式操作系统参考,其系统内核被分成两层,上层称为“内核(Kernel)”,底层则称为“硬件抽象层”。

arch Linux

今天如此庞杂的计算机,其实也是一层一层地构建起来的,从硬件层到操作系统层再到应用软件层这样构建。
分层的主要目的和好处在于屏蔽底层细节,使上层开发更加简单。
计算机领域的一个基本方法是增加一个抽象层,从而使得抽象层的上下两层独立地发展,所以在内核内部再分若干层也不足为怪。

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

思考:什么是接口?什么时候需要接口?
目前的想法接口就是造黑盒,给出输入数据的要求,内部实现不需要管。

给出一个进程调度模块的例子
来看看分层对系统内核的设计与开发有什么影响。

对于进程的理解,就是操作系统开发者为了实现多任务而提出的,并让每个进程在 CPU 上运行一小段时间,这样就能实现多任务同时运行的假象。

  1. 进程调度,它的目的是要从众多进程中选择一个将要运行的进程,当然有各种选择的算法,例如,轮转算法、优先级算法等。
  2. 进程切换,它的目的是停止当前进程,运行新的进程,主要动作是保存当前进程的机器上下文,装载新进程的机器上下文。

我们不难发现,不管是在 ARM 硬件平台上还是在 x86 硬件平台上,选择一个进程的算法和代码是不容易发生改变的,需要改变的代码是进程切换的相关代码,因为不同的硬件平台的机器上下文是不同的。

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

给出一个简单的内核设计:
在这里插入图片描述
API 接口以下的为内核空间,这才是设计、开发内核的重点

内核结构分为三层:内核硬件层,内核功能层,内核接口层

  • 内核接口层主要是定义了一套 UNIX 接口的子集;
  • 内核功能层主要完成 I/O 管理组件、内存管理组件、文件系统组件、进程管理组件、图形系统组件、网络组件、安全组件的通用功能型代码;
  • 内核硬件层则完成其内核组件对应的具体硬件平台相关的代码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值