欢迎点击关注!后续每天都会更新四条408笔记或思维导图,助力高效学习,敬请期待!
(此小节简要了解即可,考试只考这两种体系结构(大内核微内核)优缺点)
操作系统体系结构
操作系统体系结构,即操作系统的内核应该怎么设计。
考试常考:大内核,微内核。
计算机系统的层次结构
内核是操作系统最基本,最核心的部分,由一系列的内核程序组成。
实现操作系统内核功能的那些程序就是内核程序
这些内核程序必须运行在内核态
这三个部分是与硬件关联最紧密的模块,这些功能是必须放在内核当中的。
还有一些管理相关的功能
对于这些功能的管理,更多的是对数据结构的一个操作,而不会直接涉及到硬件。所以有的操作系统并不把这些管理功能放在内核当中,而只在内核当中保留与硬件接触最紧密的这些部分。
操作系统的结构,以前我们只介绍过宏内核,也就是大内核以及微内核,今年大纲又增加了分层结构,模块化的结构以及外核。
这种比较特别的操作系统结构。那个人认为这个部分如果考的话,肯定就是对各种操作系统结构特性的一个考察,以及呃,每一种结构。
它具有什么优点或者缺点?选择题大概率是以这样的角度去命题的,所以这给大家总结了各种操作系统结构的特性,以及呃,他们的这种设计思想是什么?
各自的优点缺点是什么?这个图里边标星号的这些部分是我认为更有可能在选择题当中作为选项的。呃,一些点红色星号的是全新的内容,黄色星号的是涉及到大内核和微内核。
所以都是我们比较熟悉的老内容。好,接下来我会给大家解释这个总结图里边的每一句话是什么意思,帮助你加深印象。首先来看分层结构的操作系统。
先看看图,这是分层结构的操作系统,最底层是硬件。最上层是用户接口操作系统的内核,会被分为多层。
就像一个洋葱一样,每一层它可以单向的调用,更低一层提供的接口。注意每一层,它只能调用相邻的那一层所提供的接口。
比如在这个图里边分为了一层,二层和三层这样的三个层次。那一层,它最接近于硬件,只有第一层可以直接操作硬件。
而第二层,它只能使用第一层提供的一些功能接口。第三层只能使用第二层提供的功能接口,每一层只能去调用更低的相邻,那一层提供的功能。
而不能跨层的调用好,那这种分层的设计思想造成了呃,这种结构的一些优点和缺点。先看优点。首先。
这种分层结构很便于调试和验证,只需要自底向上的逐层调试和验证就可以了。因为每一层它只会使用到相邻的低层,所提供的功能,因此这种分层结构的操作系统内核开发完了之后。
我们得调试验证它的功能是否正确。对吧,那么调试验证就可以这么做,首先第一层它只会使用到底层的硬件,而硬件厂商在出厂这个硬件的时候。
它肯定已经保证硬件的特性,没问题了,所以第一层只需要管我这一层当中的一些代码功能去验证一下,调试一下诶都OK。那么。
第一层的调试就结束了,好接下来再对第二层进行功能的调试和验证。由于第二层它只会使用到第一层提供的一些功能。而刚才我们已经调试过第一层的这些功能和代码了,确保它是没有问题的。
因此第二层的调试和验证就可以基于正确的第一层来。来进行,那么我们一层一层的往外调试,先保证更低层的功能特性,是调试过的。
被验证是OK的。然后再来调试更高一层,那这样的话,操作系统分层开发完了之后,一层一层的来分层调试是不是就变得很方便了?
就可以使得软件测试的这个过程变得很清晰明朗好,所以这是它的第一个优点,便于调试和验证。好,第二个优点易于扩充和维护各层之间的调用接口清晰固定。
因为这种分层结构的操作系统内核在设计的时候就肯定得先设计好。层与层之间的调用接口是什么样的?呃,这个函数名叫什么?以及调用的参数需要提供哪些?
各个参数的含义是什么?每一个调用又会给你返回什么东西?这些层与层之间的调用接口都是在最初设计的时候就已经规定好的。所以,由于这些层间的调用接口固定不变。
因此如果我们要在原有的两层之间再新加一层,是不是也是OK的?我们只需要保证新加的这一层向更上层提供同样的这个接口,以及新的这一层对于更下层的这个接口的使用,是不是以前?
这个更低层已经实现了,所以我们要在两层之间再扩充新的一层是很简单的,只需要保证原来定义的这个接口不变就可以了。那由于这种层间的接口固定,所以也比较方便维护。
好说完了它的优点,再来看它的缺点,分层结构的操作系统,它只能调用相邻的低层,但是我们有时候又难以合理的定义各层之间的边界。
什么意思呢?a功能有可能会调用b功能,而b功能有时候你难免也需要使用到a提供的功能。比如进程管理,有时候需要使用到内存管理相关的一些功能。
而内存管理相关的功能,有时候又需要使用到进程管理提供的一些东西。所以这种很严格的,只能由高层调用,低层的这种规定是不是就很不灵活。
有时候我们很难把操作系统内核的这些功能,把它严格的这种一层一层的给它分出来。同时,我们还要保证只能高层调用低层,这个很难。
所以这是它的第一个缺点,好第二个缺点。就是效率低,由于不可以跨层调用,所以系统调用执行的时间会很长啊。
比如说我是一个用户。我用户进行系统调用,那现在我的这个系统调用,也许它只需要使用到最底层提供的一个功能。但是最上面这一层无法直接调用。
最底层提供的这个功能接口,我只能一层一层的往下传递,就有点类似于a和d要说一句话。但是分层结构就规定a不能直接和d讲话,他只能先告诉BB。
再告诉CC,再告诉d,同时如果d要给a回话,那么d只能先给c回话c,再给b回话。
然后b再给a回话a和d之间不可以直接的进行相互的调用以及返回结果,所以这就会导致系统调用的时间。执行时间会变长,效率变低好,这是分层结构。
特别注意这两个点,我认为更有可能考。接下来,模块化的这种操作系统结构模块化是一种很经典的程序设计思想啊,会把。
操作系统的内核划分为多个模块,然后各模块之间相互协作着工作,比如说把操作系统内核分为进程管理。呃,存储器管理。
文件管理呃,以及什么设备驱动程序等等,分为多个模块,每一个模块又可以进一步划分为子模块。整个内核由主模块和可加载内核模块来组成。
那主模块就是呃必不可少的最核心,最重要的那些模块。呃,没有这些模块操作系统就无法运行,比如说呃进程管理。
呃内存管理,这些重要的模块共同组成了所谓的主模块。而可加载内核模块是可以动态加载到操作系统内核当中的,比如设备的驱动程序就属于可加载的内核模块。我有这个驱动程序。
还是没有这个驱动程序,并不会影响到系统能不能正常运行,对吧?它只是会影响到系统的一个可拓展性。如果我们加载了这个驱动程序的呃模块。
那么系统就可以支持新的设备,所以可加载内核模块算是一个锦上添花的东西。好来看一下模块化操作系统的优点,第一个优点,模块之间逻辑清晰。
易于维护,我们是按逻辑功能进行模块的划分的。有的模块专门管进程,有的模块专门管内存,所以逻辑清晰。
易于维护。同时,我们只需要确定每个模块之间的接口,就可以多模块同时进行开发。比如我的进程管理。
这个模块需要对外暴露一二三这样的三个功能接口,那只要我们规定好这三个功能接口诶函数的名字是什么?呃参数列表是什么?以及返回值是什么?那么即便我的这个模块现在还没有完成开发。
那其他的模块是不是也可以?就是同时并进啊。如果我要使用到你这个模块提供的这些功能接口,那么我按照我们提前约定好的这些模块之间的接口来开发,是不是就OK了好。
所以只要确定了各个功能模块之间的接口之后。就可以多个模块同时并行的开发,这是第一个优点,好第二个优点,这种模块化的操作系统内核通常都可以支持动态的加载一个新的内核模块。
如果想让你的操作系统支持一个新的设备,那么把这个设备驱动程序作为一个新的内核模块,加载到操作系统当中,是不是就OK了?以及如果要让操作系统支持一个新的文件系统。
那么我们把新文件系统的这些呃代码数据给它作为一个新的内核模块加载到操作系统内核里面,所以这种特性可以使得。操作系统的适应性增强。加载一个新的模块,不需要重新编译。
整个内核好,这是第二个优点。第三个优点,任何模块之间都可以直接调用其他模块,无需采用消息传递进行通信。
效率高什么意思呢?各个模块之间。我要使用你的功能,就直接调你的函数就可以了,就跟你平时写代码。
直接调一个函数一样。那这种方式可以使得功能的调用效率非常高,相比之下,在微内核结构的操作系统当中,就需要使用到消息传递的这种方式。
来调用其他模块提供的一些功能,我们一会儿再来解释好,这是第三个优点,各个模块之间可以直接相互调用,效率高。
说完优点,看它的缺点。缺点第一,模块之间的接口定义未必是合理实用的啊,就是说我这个进程管理啊。
这个模块。本来只提供这样的三个功能,但是开发的过程当中,你可能会发现诶其他模块好像还需要使用到一个新的功能,对吧?
所以,由于各个模块之间可能相互调用会比较多,因此在开发各个模块的时候,这个接口定义可能是比较难的。好。
另外模块之间相互依赖,难以调试和验证,就是说我这个模块之间你调我,我调你,我们相互调对吧?
那这样的话,如果我调试的时候发现。哎,我这个模块好像功能出了问题,那到底是我模块本身的问题。
还是我调用的这个东西,它的问题还是说我调了它,然后它又调了我之后才产生的问题?所以就会导致这个调试和验证会比较困难,那相比之下。
这种分层结构其实它也是一种模块化的设计思想,对吧?每一层就是一个模块嘛。但是,分层结构的这些模块之间有一个很清晰的单向依赖的关系。
高层可以调用更低一层,所以分层结构在调试和验证的时候呃,显然就会更容易一些。好,这是模块化的缺点。
重点注意打红心的这两个特点。好,接下来宏内核和微内核,这是我们比较熟悉的东西,宏内核呢。
就是要把呃所有的这些系统功能都放在内核里边。事实上,宏内核它也采用了模块化的设计思想,我们给了这样的一个图,在内核当中有进程管理呃。
存储管理,设备管理以及和硬件关系最紧密的什么中断处理,源于时钟管理等等。这所有的这些功能都放在内核里边,整个内核里边的各种功能之间也是可以直接相互调用的。
就跟普通的函数调用一样。那相比之下,微内核只会把最基本的与硬件最紧密的一些功能放在内核当中,大多数的功能会被放在微内核之外。那在这种情况下。
功能和功能之间的调用就没有那么方便了,进程管理想要调用存储管理相关的功能。它只能通过消息传递的方式来进行进程管理的模块,向v内核发送一个消息。那这个消息里边呃。
就是指明了哎,我想要调用谁,我给他的这个调用参数是什么好,然后会由微内核的进程间通信相关的这个功能。把他的这个消息传递给存储管理这个模块好。
然后这个模块接收到进程管理的这个消息之后。它才会处理这个调用的请求,同时如果要返回这个调用的结果,那同样的也是需要通过消息传递的方式。让v内核来协助呃各个模块之间的这种调用以及返回。
那显然直接进行函数调用肯定要比通过消息传递来通信来调用要快得多。好,所以大内核通常性能会更好,而微内核它的性能会更差。那微内核由于内核更小。
功能更少,所以对于内核的这个维护是不是就变得更简单?同时内核它越简单,可靠性肯定也越高。另一方面。
由于各个功能模块都被放到了内核之外,所以某一个功能模块出错并不会导致整个系统的崩溃。但是对于大内核来说,只要某一个功能模块出错,那由于这些模块之间相互依赖很强。
所以内核中任何一个功能模块出错,就有可能导致整个系统内核崩溃。好,那这是大内核和微内核,都是我们比较熟悉的东西。
好,最后一种操作系统结构叫做外核,这种结构的操作系统非常少见,我在维基百科找了这样的一个结构图。这是硬件。
这是内核。这个部分是外合。这是应用程序。应用程序可以通过呃系统提供的这些库函数去调用普通内核的一些功能。也可以通过库直接去调用外核所提供的一些功能。
所以这种操作系统,它由内核,外核两个部分来组成,那在这种系统当中。内核的部分。
它只负责进程,调度进程,通信等等这些功能,而外核这个部分会负责为用户进程分配。未经抽象的硬件资源。
比如说磁盘的存储空间,内存的存储空间,这些硬件资源都是由外核来负责管理的。而内核只管什么进程,调度进程。
通信这些和硬件资源分配回收无关的这些工作。好来解释一下,什么叫做给用户进程分配未经抽象的硬件资源,我们知道。在普通的操作系统当中。
如果用户进程他想要申请使用一片内存空间。那么,给他分配的内存空间是经过抽象的,经过虚拟化的用户进程,他自己看到的视角。
似乎是自己拥有了一整片连续的这个内存空间,但事实上,这只是虚拟的地址,空间操作系统内核会把这些虚拟页面。映射到实际的物理页框当中。
这些物理页框在内存当中通常是离散的好,所以普通的操作系统。给进程分配的这个呃内存空间其实是经过抽象的,经过虚拟化的。除了内存空间之外。
给进程分配的文件存储空间外,存空间也是经过抽象的。对于进程来说,他觉得自己的文件好像是连续的呃,一个地址空间对吧?
但事实上,这个文件的各个块在磁盘当中很有可能是被离散的存放的。所以普通的操作系统给用户进程分配的这个磁盘空间,也是经过抽象的。那回到外核这种操作系统。
外核可以给用户进程直接分配未经抽象的这种硬件资源。这样的资源管理策略,在有的时候会很有作用,比如一个用户进程,他很有可能知道自己的这一片呃存储空间。
是经常需要随机访问的,一会访问a这个地方,一会访问b这些地方,那如果给这个用户进程分配的磁盘空间。在外存当中是离散的这一块那一块。
那么用户进程在随机访问他这些呃文件块的时候。是不是意味着这个词头需要来回横跳啊?那这样就会导致用户进程对自己的文件随机访问的这种性能效能变低。因为用户进程的这个文件在外存当中,到底被零散的分布到哪些位置是完全由操作系统来决定的?
用户进程自己并不能控制,而如果采用外核的这种策略,那么外核可以直接给用户进程分配。未经抽象的硬件资源。也就是说。
如果这个用户进程他知道自己的这个文件需要频繁的被随机访问,那么我就可以向外核申请。给我分配一整片连续的这个磁盘块,比如说从零号块到一零二四号块,全部都是我的。
好,那么用户进程,他的这些文件数据直接存放到连续的几个磁盘块当中,那他之后想要随机访问自己这个文件里边的任何一块。是不是磁头移动的这些距离就会变少?
那这样性能就会提升好,所以外核能够给用户进程直接分配一个未经抽象的。系统资源,这在有的情况下是非常有用的,那除了外存的分配。
内存的分配也是一样。这是一个物理内存。在有外核的这种操作系统当中,一个应用程序完全可以向外核申请给自己分配连续的一整片物理内存空间。从a到b这个地址都是我的D盘外核。
给用户进程分配的这个内存区域也是未经抽象的。用户进程看到的就是一片实实在在的物理地质空间,而不是虚拟的,经过抽象的地质空间。那外核除了分配回收这些未经抽象的硬件资源之外。
它还需要负责保证这些硬件资源的使用安全。比如a到b这个空间已经分配给了这个进程,那么另一个进程p2想要访问这片区域。外核就需要及时的发现并且制止,同时原本的这个进程如果要访问a和b之外的其他空间。
这个行为也应该被外核发现并制止。所以外核它分配了这些硬件资源之后,还需要保证这些硬件资源的使用安全。好,那由于给用户进程分配的是不虚拟。
不抽象的这种硬件资源,因此用户进程在使用这些硬件资源的时候就可以更灵活。同时,这种硬件资源的分配方法也减少了虚拟硬件资源的映射层,也提升了效率。
什么意思?普通的操作系统给用户进程分配的都是虚拟的硬件资源,比如说虚拟内存,那么一个用户进程。他在访问自己的地址空间的时候。
他只能提供虚拟地址,而操作系统需要去查页表,甚至查二级,三级页表,通过多次的访存才能够把虚拟地址。
转换成实际的物理地址,那把这个虚拟地址映射到实际的物理地址,这个映射的过程是不是需要一些时间的代价?就会降低系统的整体效率,而对于外核这种结构来说。
我给进程分配的就是a到b这片区域那。那只要进程,你访问的这个呃物理空间是在a到b之内,那你就直接访问就行了,操作系统不需要帮你进行地址映射。
这就可以使得效率提升。好,这是外核的优点,那外核的缺点呢?就是降低了系统的一致性。
什么意思呢?在有外核的这种操作系统当中。有的进程p1他申请的可能也是一个虚拟的地址空间,然后系统还要帮我映射,有的进程p2他申请的可能就是一个物理的呃地址空间。
就操作系统,不需要帮它映射,所以给各个进程分配内存外存的这种呃策略,以及后续的一些管理,是不是就需要考虑到各种各样的情况。
所以就降低了系统的一致性?会使得系统变得更加复杂,好,那这就是外核这种操作系统结构。那到此为止。
我们就把所有的这些操作系统结构给捋了一遍。大家可以再结合这一页PPT,自己再捋一遍。