精华内容
下载资源
问答
  • 微内核
    千次阅读
    2019-08-28 18:47:44

    宏内核和微内核的基本概念

        宏内核:简单来说,就是把很多东西都集成进内核,例如linux内核,除了最基本的进程、线程管理、内存管理外,文件系统,驱动,网络协议等等都在内核里面。将内核从整体上作为一个大过程实现,并同时运行在一个单独的地址空间。所有的内核服务都在一个地址空间运行,相互之间直接调用函数,简单高效。

    优点:效率高

    缺点:稳定性差、开发过程中的bug经常会导致整个系统挂掉

     

        微内核:内核中只有最基本的调度、内存管理。驱动、文件系统等都是用户态的守护进程去实现的,微内核中功能被划分成独立的过程,过程间通过IPC进行通信。模块化程度高,一个服务失效不会影响另外一个服务。

    优点:超级稳定,驱动等的错误只会导致相应进程死掉,不会导致整个系统都崩溃,做驱动开发时,发现错误,只需要kill掉进程,修正后重启进程就行了,比较方便。

    缺点:效率低。典型代表QNX,QNX的文件系统是跑在用户态的进程,称为resmgr的东西,是订阅发布机制,文件系统的错误只会导致这个守护进程挂掉。不过数据吞吐量就比较不乐观了。

    Linux是宏内核还是微内核?

        Linux是一个单内核结构,同时又吸收了微内核的优点:模块化设计,支持动态装载内核模块。Linux还避免了微内核设计上的缺陷,让一切都运行在内核态,直接调用函数,无需消息传递

        Linux大部分都是单内核的。

    宏内核、微内核详解

        微内核(Microkernel kernel)――在微内核中,大部分内核都作为单独的进程在特权状态下运行,他们通过消息传递进行通讯。在典型情况下,每个概念模块都有一个进程。因此,假如在设计中有一个系统调用模块,那么就必然有一个相应的进程来接收系统调用,并和能够执行系统调用的其他进程(或模块)通讯以完成所需任务。

        在这些设计中,微内核部分经常只是个消息转发站:当系统调用模块要给文档系统模块发送消息时,消息直接通过内核转发。这种方式有助于实现模块间的隔离。(某些时候,模块也能够直接给其他模块传递消息)在一些微内核的设计中,更多的功能,如I/O等,也都被封装在内核中了。但是最根本的思想还是要保持微内核尽量小,这样只需要把微内核本身进行移植就能够完成将整个内核移植到新的平台上。其他模块都只依赖于微内核或其他模块,并不直接直接依赖硬件。

        微内核设计的一个长处是在不影响系统其他部分的情况下,用更高效的实现代替现有文档系统模块的工作将会更加容易。我们甚至能够在系统运行时将研发出的新系统模块或需要替换现有模块的模块直接而且迅速的加入系统。另外一个长处是无需的模块将不会被加载到内存中,因此微内核就能够更有效的利用内存。


        单内核(Monolithic kernel)――单内核是个很大的进程。他的内部又能够被分为若干模块(或是层次或其他)。但是在运行的时候,他是个单独的二进制大映象。其模块间的通讯是通过直接调用其他模块中的函数实现的,而不是消息传递。

        单内核的支持者声称微内核的消息传递开销引起了效率的损失。微内核的支持者则认为因此而增加的内核设计的灵活性和可维护性能够弥补任何损失。

        这种争论经常会令人想到前几年CPU领域中RISC和CISC的斗争。现代的成功CPU设计中包含了任何这两种技术,就像Linux内核是微内核和单一内核的混合产物相同。Linux内核基本上是单一的,但是他并不是个纯粹的集成内核。前面一章所介绍的内核模块系统将微内核的许多长处引入到Linux的单内核设计中。(顺便提一下,我考虑过一种有趣的情况,就是Linux的内核模块系统能够将系统内核转化成为简单的不传递消息的微内核设计。虽然我并不赞成,但是他仍然是个有趣的想法。)

        为什么Linux必然是单内核的呢?一个方面是历史的原因:在Linus的观点看来,通过把内核以单一的方式进行组织并在最初始的空间中运行是相当容易的事情。这种决策避免了有关消息传递体系结构、计算模块装载方式等方面的相关工作。

        另外一个原因是充足的研发时间的结果。Linux既没有研发时间的限制,也没有深受市场压力的发行进度。任何的限制只有并但是分的对内核的修改和扩充。内核的单一设计在内部实现了充分的模块化,在这种条件下的修改或增加都并不怎么困难。而且问题还在于没有必要为了追求尚未证实的可维护性的微小增长而重写Linux的内核。(Linus曾多次特别强调了如下的观点:为了这点利益而损耗速度是不值得的)后面章节中的部分内容将周详的重新考虑充足研发时间的效果。

        假如Linux是纯微内核设计,那么向其他体系结构上的移植将会比较容易。实际上,有一些微内核,如Mach微内核,就已成功的证实了这种可移植性的长处。实际的情况是,Linux内核的移植虽然不是很简单,但也绝不是不可能的:大约的数字是,向一个全新的体系结构上的典型的移植工作需要 30,000到 60,000行代码,再加上不到20,000行的驱动程式代码。(并不是任何的移植都需要新的驱动程式代码。)粗略的计算一下,我估计一个典型的移植平均需要50,000行代码。这对于一个程式员或最多一个程式小组来说是力所能及的,能够在一年之内完成。虽然这比微内核的移植需要更多的代码,但是 Linux的支持者将会提出,这样的Linux内核移植版本比微内核更能够有效的利用底层硬件,因而移植过程中的额外工作是能够从系统性能的提高上得到补偿的。

        这种特别设计的权衡也不是很轻松就能够达到的,单内核的实现策略公然违背了传统的看法,后者认为微内核是未来发展的趋势。但是由于单一模式(大部分情况下)在Linux中运行状态良好,而且内核移植相对来说比较困难,但没有明显地阻碍程式员团体的工作,他们已热情高涨地把内核成功的移植到了现存的大部分实际系统中,更不用说类似掌上电脑的一些看起来很不实际的目标了。只要Linux的众多特点仍然值得移植,新的移植版本就会不断涌现。

        所有的Unix内核都同宗同源,并且提供相同的API,现代的Unix内核存在许多设计上的相似之处。Unix内核几乎毫无例外的都是一个不可分割的静态可执行块(文件)。也就是说,它们必须以完整、单独的可执行块的形式在一个单独的地址空间中运行。

        Unix内核几乎都需要硬件系统提供页机制以管理内存。这种页机制可以加强内存空间的保护,并保证每个进程都可以运行于不同的虚地址空间上。

    单内核与微内核设计比较

        操作系统内核可以分为两大设计阵营:单内核和微内核(第三阵营外内核,主要用在科研系统中,但也逐渐在现实世界中壮大起来)。

        单内核是两大阵营中一种较为简单的设计,在1980年之前,所有的内核都设计成单内核。所谓单内核就是把它从整体上作为一个单独的大过程来实现,并同时运行在一个单独的地址空间。因此,这样的内核通常以单个静态二进制文件的形式存放于磁盘。所有内核服务都在这样的一个大内核空间中运行。内核之间的通信是微不足道的,因为大家都运行在内核态,并身处同一地址空间:内核可以直接调用函数,这与用户空间没有什么区别。这种模式的支持者认为单模块具有简单和高性能的特点。大多数Unix系统都设计为单模块。

        另一方面,微内核并不作为一个单独的大过程来实现。相反,微内核的功能被划分为独立的过程,每个过程叫做一个服务器。理想情况下,只有强烈请求特权服务的服务器才运行在特权模式下,其他服务器都运行在用户空间。不过,所有的服务器都保持独立并运行在各自的地址空间。因此,就不可能像单模块内核那样直接调用函数,而是通过消息传递处理微内核通信:系统采用了进程间通信(IPC)机制,因此,各种服务器之间通过IPC机制互通消息,互换“服务”。服务器的各自独立有效地避免了一个服务器的失效祸及另一个。

        同样,模块化的系统允许一个服务器为了另一个服务器而换出。因为IPC机制的开销比函数调用多,又因为会涉及内核空间到用户空间的上下文切换,因此,消息传递需要一定的周期,而单内核中简单的函数调用没有这些开销。基于此,付之于实际的微内核系统让大部分或全部服务器位于内核,这样,就可以直接调用函数,消除频繁的上下文切换。Windows NT内核和Mach(Mac OS X的组成部分)是微内核的典型实例。不管是Windows NT还是Mac OS X,都在其新近版本中不让任何微内核服务器运行在用户空间,这违背了微内核设计的初衷。

        Linux是一个单内核,也就是说,Linux内核运行在单独的内核地址空间。不过,Linux汲取了微内核的精华:其引以为豪的是模块化设计、抢占式内核、支持内核线程以及动态装载内核模块的能力。不仅如此,Linux还避其微内核设计上性能损失的缺陷,让所有事情都运行在内核态,直接调用函数,无需消息传递。至今,Linux是模块化的、多线程的以及内核本身可调度的操作系统。实用主义再次占了上风。

        当Linus和其他内核开发者设计Linux内核时,他们并没有完全彻底地与Unix诀别。他们充分地认识到,不能忽视Unix的底蕴(特别是 Unix的 API)。而由于Linux并没有基于某种特定的Unix,Linus和他的伙伴们对每个特定的问题都可以选择已知最理想的解决方案—在有些时候,当然也可以创造一些新的方案。以下是对Linux内核与Unix各种变体的内核特点所作的分析比较:

    • Linux支持动态加载内核模块。尽管Linux内核也是单内核,可是允许在需要的时候动态地卸除和加载部分内核代码。

    • Linux支持对称多处理(SMP)机制,尽管许多Unix的变体也支持SMP,但传统的Unix并不支持这种机制。

    • Linux内核可以抢占(preemptive)。与传统的Unix不同,Linux内核具有允许在内核运行的任务优先执行的能力。在其他各种Unix产品中,只有Solaris和IRIX支持抢占,但是大多数传统的Unix内核不支持抢占。

    • Linux对线程支持的实现比较有意思:内核并不区分线程和其他的一般进程。对于内核来说,所有的进程都一样—只不过其中的一些共享资源而已。

    • Linux提供具有设备类的面向对象的设备模型、热插拔事件,以及用户空间的设备文件系统(sysfs)。

    • Linux忽略了一些被认为是设计得很拙劣的Unix特性,像STREAMS,它还忽略了那些实际上已经根本不会使用的过时标准。

    • Linux体现了自由这个词的精髓。现有的Linux特性集就是Linux公开开发模型自由发展的结果。如果一个特性没有任何价值或者创意很差,没有任何人会被迫去实现它。相反的,在Linux的发展过程中已经形成了一种值得称赞的务实态度:任何改变都要针对现实中确实存在的问题,经过完善的设计并有正确简洁的实现。于是,许多其他现代Unix系统包含的特性,如内核换页机制,都被毫不迟疑的引入进来。

    不管Linux和Unix有多大的不同,它身上都深深地打上了Unix烙印

    更多相关内容
  • 混合内核实质上也是微内核,而外内核是一种比较极端的设计方法,目前还处于研究阶段,所以我们就着重讨论宏内核与微内核两种内核。
  • 为减小驱动重新开发带来的弊端,提出了一种基于UHomeOS的微内核实现驱动复用的技术,通过虚拟机实现重用设备驱动的方式,解决了驱动复用过程中通用性较差、复用过程复杂、计算机资源占用过高等问题。
  • 设计并实现了一个运行在Bochs虚拟机上的微内核结构的操作系统,详细描述了系统中进程管理、进程间通讯、基本内存管理、磁盘服务器以及文件服务器的设计和实现。并将实现的系统应用于安全路由器的开发中。本系统的...
  • 摘要:介绍嵌入式微内核实时操作系统的体系结构;针对Wolf嵌入式操作系统,设计一套微内核嵌入式操作系统测试实现方案。在Wolf操作系统支持下,已产业化的阅读不耗电电子书(eBook)验证了Wolf操作系统的可靠性。 ...
  • Tango 是一个微内核的Go语言Web框架,采用模块化和注入式的设计理念。开发者可根据自身业务逻辑来选择性的装卸框架的功能,甚至利用丰富的中间件来搭建一个全栈式Web开发框架。
  • 针对嵌入式处理器微内核的结构特点,结合32位微处理器“龙腾C1”,提出了一种微内核的低功耗设计方法。在体系结构层次上,分别从微操作ROM、微堆栈和微操作编码几个不同角度出发,对嵌入式处理器的微内核进行了功耗...
  • 火龙果软件工程技术中心 这两年基于流程引擎技术构建的应用系统越来越受到客户的追捧和认可,能否支持“流程可定制、可更改、可运行”也逐渐成为客户衡量一个应用系统主要标准之一。又比如目前被大家广泛提及的SOA...
  • 寄居架构和裸金属架构是虚拟机软件常采用的两种技术模式,其中裸金属模式虚拟机又分为微内核和单内核 两种技术架构,与单内核架构相比,微内核具有更高的安全性,Hyper-V采用的是微内核架构。在对微内核架构技术详 细...
  • 基于微内核架构的实时虚拟化技术的研究
  • 如何实现一个微内核操作系统的设计
  • 自然的做法:凡是为进程服务的模块就应放在操作系统的内核中。例如:文件管理模块是为进程服务的,所以应放在内核中;设各驱动模块是为进程服务的,所以要放在内核中;进程管理模块当然也要放在内核中。随着进程对...
  • Linux微内核模型.pdf

    2021-09-06 23:41:27
    Linux微内核模型.pdf
  • 因此,这就给设计小内核创造了条件。  相对于通用计算机系统而言,内存在嵌人式系统中是更为稀缺珍贵的资源。因此,作为需要常驻内存的操作系统的内核,在满足应用的前提下越小越好。  另外,为了满足不同的应用...
  • 关于微内核的定义,这里有一份简单的描述:内核运行在内核态,只包含基本的多任务调度功能;其他系统服务都运行在用户态,包括文件系统,网络协议栈,甚至内存管理,驱动都是一个个独立的用户态进程,并相互做内存...
  • 基于微内核L4的一种安全网络架构模型分析,李灿煜,周庆国,本文给出了一个基于微内核L4的安全网络架构模型。在本文中提出的模型中,设备驱动并非内核的一部分,而是运行在微内核L4之上的一��
  • 操作系统微内核架构研究

    千次阅读 2020-11-18 17:02:46
    微内核是操作系统内核的一种,在工控系统...本文较为全面地研究了微内核技术的各个方面,包括微内核的定义、微内核的体系架构、微内核的发展历史、微内核的特点、微内核的应用场景,以及麒麟软件所进行的部分研究工作。

    1 简介

    微内核是操作系统内核的一种,在工控系统、嵌入式系统、实时系统等领域发挥着重要作用。本文较为全面地研究了微内核技术的各个方面,包括微内核的定义、微内核的体系架构、微内核的发展历史、微内核的特点、微内核的应用场景,以及作者所进行的部分研究工作。本文部分内容和图来自网上,由于内容较多,有些没有标注,如果原作者觉得不合适请联系删除。

    2 微内核的定义

    在计算机科学中,内核是操作系统的核心部分,它管理着系统的各种资源,譬如时钟、中断、存储、进程、设备驱动、原语等。应用程序运行在内核之上,并通过系统调用访问内核空间。

    从内核架构来划分,操作系统内核可分为微内核(Micro Kernel)和宏内核(Monolithic Kernel,也翻译为单内核)。如下图所示,微内核操作系统仅在内核中保留了调度、基础IPC、虚拟内存管理等少数核心功能模块,它们位于内核空间,而操作系统的其他功能模块(譬如文件系统、驱动程序等)与用户应用程序一起运行于用户空间;宏内核操作系统在内核中包括了整个操作系统的大部分功能模块(譬如文件系统、驱动程序等),并且这些系统模块都运行在同一个内核地址空间,模块之间通过简单的系统调用进行协调工作。

    微内核(通常缩写为μ内核)由一群数量尽可能最少的软件程序组成,它们负责提供实现一个操作系统所必须的各种机制。这些机制就是之前提到的线程/进程调度机制、基础的进程间通信机制(IPC)、虚拟内存管理机制等;而包括文件系统、驱动程序在内的其他各种功能模块都放到用户空间。微内核的最小化也称为Jochen Liedtke最小化原则。Jochen Liedtke是一名德国科学家。这里区分两个术语,操作系统微内核即指微内核,微内核操作系统则指一种基于微内核架构的操作系统。

                                             图1 微内核与宏内核架构

    从操作系统功能模块来看,操作系统厂商依据自己的实际情况,可以将宏内核操作系统中的部分功能模块从内核空间移到用户空间,也可以将微内核操作系统中的部分功能模块从用户空间移到内核空间,由此就构成了微内核、小内核、大内核、宏内核等称谓。对于介于微内核和宏内核之间的小内核、大内核来说,有时也把它们称之为混合内核。对于操作系统厂商来说,没有必要严格遵守微内核的最小化原则,非要做一个严格意义上的微内核,或者完全意义上的宏内核。本文在后面主要讨论微内核和宏内核。

    3 微内核的体系架构

    3.1 分布式服务器架构

    在图1的微内核架构中,按照官方说法,位于用户空间的各个功能模块被设计成一个个功能独立的服务器(Server),由微内核采用消息通信机制来调度各个服务器完成工作。为避免混淆,这里的服务器可以理解为一个服务器程序。微内核相当于客户端程序(Client)。

    从理论上来说,基于消息通信的两个程序(Client和Server)可以位于同一台机器,也可以位于不同机器。因而,微内核操作系统中的这些服务器可以是分布式的,它们可能位于同一台机器,也可能位于其他机器。这里再次强调,只是理论上是这样,真正这样实现的操作系统还极少。

    微内核的分布式架构是有意义的。从下面链接可知,鸿蒙操作系统声称自己具有两个特点:微内核、分布式。采用分布式消息通信机制,可以实现鸿蒙操作系统与各类硬件设备(例如手机、平板、手表、PC等)的互联。这种消息通信机制也被说成为分布式总线。

    (参见:鸿蒙系统:微内核,分布式_华为

                                            图2 基于分布式总线的鸿蒙操作系统的万物互联机制

    3.2 插件架构

    在图1的微内核架构中,各个服务器程序相互独立,也有个别人把这种架构称之为“插件架构”。

    如下图所示(微内核架构 - 简书),在软件开发领域,插件化架构由一个中间的核心系统和若干插件模块组成。该架构最大的优势是允许第三方开发者遵循一定的开发规范添加额外的插件化应用。采用插件架构的软件有很多,例如Eclipse、企业ERP软件等,这类软件自身具备丰富功能,同时支持第三方应用的即插即用;并且第三方插件化程序的安装、运行、卸载以及故障不会对原有系统造成任何影响。

                                            图3 软件插件架构

    在插件架构中,核心系统的功能稳定,很少变更。它只拥有能使应用运行的最小功能逻辑(例如插件模块的注册、加载、卸载,以及插件模块之间的相互通信等)不涉及任何特定业务;插件系统具备良好的扩展性,可根据特定业务需求而变更其业务逻辑。
    插件架构本质上是将一个软件系统中的变化部分封装在插件中,从而实现不同业务之间的隔离性,达到系统快速灵活扩展的目的,同时所有特定业务相关逻辑的变更不会影响整体系统的稳定性。

    另外,插件架构需要解决好三方面的问题:插件管理、插件链接和插件通信。

    由上可知,理论上的微内核确实是一种基于插件架构的操作系统内核。

    4 微内核的发展历史

    4.1 微内核起源(参见维基百科)

    微内核的起源可以追溯到丹麦计算机先驱Per Brinch Hansen和他在丹麦计算机公司Regnecentralen任职期间的工作。当时,他领导了RC 4000计算机的软件研发。1967年,Regnecentralen正在普瓦伊的一家波兰化肥厂安装RC 4000原型机。这台计算机使用了一个小型的专门为工厂量身打造的实时操作系统。Brinch Hansen和他的团队开始关注RC 4000操作系统缺乏通用性和可重用性。他们担心每次在其他公司安装一台新机器都需要开发不同的操作系统,1969年,最终完成了RC 4000多道程序设计系统。它的内核提供了基于消息传递的进程间通信,最多可以为23个非特权进程提供进程间通信,其中每次有8个进程相互保护。

    继Brinch Hansen的工作之后,自20世纪70年代以来,人们开始开发微内核,但“微内核”这个术语大概在1981年之前才首次出现。最早的操作系统内核一直都是宏内核,不过早期的宏内核操作系统因为功能过于简单而更像一个微内核操作系统。随着计算机技术的发展,新的设备驱动程序、协议栈、文件系统和其他低级系统不断出现导致宏内核一直处在开发过程中,因此需要为管理这些代码花费大量的时间。由此,微内核提出了一个新理念:所有这些新出现的服务都要像其他程序一样作为用户空间程序来实现,允许它们像任何其他程序一样单独工作、启动和停止。这不仅可以让这些服务更容易操作,而且还可以分离内核代码,使其能够进行微调,而不必担心意外的副作用。采用这种方式,操作系统的内核部分就不会频繁修改,进而便于维护和管理。

    在20世纪80年代,当第一个可用的局域网出现时,微内核是一个非常热门的话题。AmigaOS Exec内核就是一个早期的例子,它于1986年引入,并在一台在商业上相对成功的PC中得到了使用。

    4.2 三代微内核

    操作系统微内核技术起始于20世纪80年代,起初被设计用来解决传统宏内核操作系统在可维护性、扩展性、可靠性和稳定性方面的诸多问题。但是伴随着微内核思想的进一步发展,最终形成了一整套操作系统设计的核心理念,即操作系统微内核仅提供最简单、基本的服务,如通信功能,而操作系统的普通服务,如文件管理、设备管理、网络管理等则在微内核以外提供。

    4.2.1 第一代微内核操作系统

    以Mach为代表,Mach微内核操作系统试图从架构上重构宏内核操作系统但是仍然能够维持原有操作系统功能的一次尝试。为此,Mach微内核研究出了一系列概念用来支撑该项目,其中较突出的有核外页管理器和用户空间设备驱动等。Mach采用的IPC(进程间通信)策略包括消息传递、RPC(远程过程调用)、同步和通知等。

    然而,包括Mach或IBM的Workplace的第一代微内核的性能都不佳。对于Mach3来说,比原来的宏内核UNIX运行慢了约50%。最终大部分人倾向于认为性能低的原因是因为IPC开销过大引起的,也有提出其他原因的。

    以用户程序读写文件时所涉及到的文件操作的上下文切换为例:

    1. 宏内核在内核空间和用户空间之间有2次切换:用户程序<--->宏内核(来回各1次);
    2. 微内核有8次切换:用户程序<--->微内核<--->文件服务器<--->微内核<--->磁盘设备驱动器。

    4.2.2 第二代微内核操作系统

    以L3、L4为代表,第一代微内核从概念上验证了微内核技术的可行性,但是因为性能上的原因,并未在产业界引起大规模推广,但相关学术研究不断出现。鉴于第一代微内核在性能上的劣势,Jochen Liedtke设计了高性能的第二代微内核L4。相对于第一代微内核,第二代微内核不再是传统Unix操作系统的简单重构,而是一种全新的设计,并具有较高的性能。

    L4内核支持三种抽象概念:地址空间,线程和IPC。它只提供7 个系统调用,且仅有12K字节代码。进程间通信的一个基本问题是数据需要跨越不同的地址空间。大多数操作系统的解决办法是用两次数据拷贝:用户地址空间A->内核地址空间->用户地址空间B。为了实现高性能的IPC,L4的解决办法是通过暂时地址映射实现了1次拷贝:内核把数据的目的地址暂时映射到一个位于内核地址空间的通讯窗口,然后内核把数据从用户A 地址空间拷贝到通讯窗口供用户B 使用。L4还采用了许多新颖的技术来提高内核性能,例如直接地址转换、懒惰调度(Lazy Scheduling)、使用寄存器传送短消息、减少缓存及TLB Miss等。

    4.2.3 第三代微内核操作系统

    以seL4为代表,第三代微内核更强调安全性。seL4由澳大利亚人开发,是在第二代微内核L4基础上发展起来的。L4作为第二代微内核,通过采用同步IPC技术以及使用寄存器而非内存拷贝的方式来传递消息,解决了第一代微内核的性能低、实时性差的问题;但是第二代微内核在设计时为了追求高性能,所使用的线程ID是一种全局共享静态资源,任何任务中的线程都可以通过线程ID向其他服务器线程发起服务请求,由此形成了安全上的隐患。作为第三代微内核,seL4通过一种类似对象引用的机制即Capability进行调用,任何操作系统内核对象如线程、中断、内存等都不能直接进行操作,由此解决了第二代微内核的安全隐患问题。seL4本身就是security L4的意思。

    总之,微内核技术从第一代发展到了第三代。第一代微内核停留在概念层面,试图从概念上印证微内核技术的可行性;第二代微内核更关心性能,在第一代微内核的基础上印证微内核技术的可用性;第三代微内核则关注安全性。

    5 微内核的特点

    5.1 安全性、可靠性、可移植性、可维护性

    在安全性方面,通常认为微内核操作系统比宏内核操作系统更安全。微内核之上的模块之间相对独立,单个模块崩溃后可以重启,通常不影响全局;宏内核的模块之间因为都在内核内而纠缠在一起,一个模块的崩溃容易导致整个系统的失败。宏内核不安全的核心问题在于其不符合最低授权原则POLA(Principle Of Least Authority)。其中,最大的隐患在于宏内核可不断扩张的内核模块。例如,对Linux来说,一旦进入内核,所有的代码都运行在CPU最高等级Ring 0,内核级的恶意软件可以破坏中断表、系统调用表等关键数据。然而,在微内核架构中,进程管理、文件系统、网络服务等均运行在Ring 1并且没有动态扩展,微内核的这种封闭性很好地保障了隔离性,当然这种隔离性也带来了性能开销。

    另外,由于内核较小,微内核操作系统相比宏内核操作系统还具有可靠性好、可移植性好、可维护性好的特点。

    5.2 可扩展性

    从可扩展性来看,微内核操作系统只在内核部分包括功能几乎不变的核心模块,其他模块位于内核之上,便于扩展新的模块;宏内核操作系统则在内核部分包括了大部分操作系统功能模块,添加新模块会影响到其他模块,因而不便于扩展。

    5.3 可连续性

    在工控领域,有些系统可以连续运行几个月甚至几年。可连续性是指长时间运行而不重启;当然,如果失败后应能很快恢复运行。相比宏内核,微内核因为功能少,安全性和可靠性高,因而具有更好的连续性。

    5.4 性能

    宏内核操作系统因为在内核部分包括了大部分操作系统功能模块,这些模块只需要通过函数调用的方式就可以完成相互间的调用。但是,微内核操作系统的大部分功能模块在内核之外,需要通过上下文切换和地址空间(用户空间和内核空间)切换才能够完成。这样,微内核的性能通常认为比宏内核差。但即便如此,也有观点认为微内核因为其他各种优点而会在未来的PC、服务器等领域占有一席之地。

    5.5 实时性

    微内核与实时性没有必然联系。因为性能和实时性是两个不同的概念,所以把实时性放在性能之后来讨论。实时内核的对比对象是分时内核或非实时内核。实时内核要求系统响应的实时性,比如火箭、无人机等的操作系统就是实时的,要求对系统的各种状态做立即处理;而分时系统则对任务做分时处理,平分处理器时间,所以不具备实时性。由于一些微内核操作系统在实时性方面做了处理,因而具有较好的实时性,但宏内核操作系统也可以在实时性方面进行优化处理。

    6 微内核与宏内核架构之争

    Minix和Linux是两个著名的开源操作系统,Minix于1987年发布,主要用于教学;Linux最早在1991年发布,而1.0正式版本则在1994年发布。

    Minix采用微内核架构,Linux采用宏内核架构,那么这两种架构到底谁更胜一筹呢?在1992年,Minix的发明者Andrew S. Tanenbaum和Linux的创始人Linus Benedict Torvalds为此有过一段著名的争论。不过那时候,Linux才刚刚开始。看看两位大佬的争论,对我们会有所启发。(参见:https://www.cnblogs.com/wickedboy237/archive/2013/05/12/3074009.html,邮件中是Andy Tanenbaum)

    Andrew主要观点:

    (1)微内核架构优于宏内核架构。

    (2)Linux采用宏内核架构过时了,那是一些老的操作系统采用的方法,譬如UNIX, MS-DOS, VMS, MVS, OS/360, MULTICS。这是从90年代退回到70年代的一种设计方法,就像把一个正在运行着的C程序用BASIC重写了。在1991年还写一个宏内核操作系统真是一个愚蠢的选择。

    (3)宏内核唯一可称道的地方就是性能,但现在有足够的证据表明微内核系统也能够和宏内核系统跑得一样快(比如Rick Rashid 发表的对 Mach 3.0 和宏内核系统对比的论文)。

    (4)微内核架构的可移植性更好,没有必要为所有的CPU都设计一个不同的宏内核。譬如不断涌现的那些Intel CPUs: 8008、8080、8086、8088、80286、80386、80486,一直到子子孙孙无穷尽。

    Linus主要观点:

    (1)Linux几乎在所有的领域里面都能战胜Minix。

    (2)Minix并没有把微内核的能力发挥出来,并且对于真正的在内核中的多任务处理还有问题。

    (3)事实是Linux可移植性比Minix好。可移植性的存在是为了那些不会编程的人。可移植性是个好东西,但只在有意义的前提下。尝试着把一个操作系统变得可移植没有必要,其实只要附带一个轻便的API就足够了(例如POSIX标准)。一个操作系统的理念是利用硬件的特点,并且把他们隐藏在一层层的高级调用中。当然这也使得内核变得不大有移植性,但它也变得更容易设计。

    从1992年到2020年,世间发生了太多变化:计算机性能变得越来越好,体积越来越小;Linux变得越来越流行;计算机用户越来越年轻。由于Linux庞大的开发者和用户群体,Linux也被开发者们移植到各类CPU架构中,并没有因为可移植性而受到阻碍。

    7 微内核的应用场景

    在微内核的发展过程中,出现了很多的微内核操作系统,譬如:Mach、Fiasco.OC、Pistachio OKL4 Microvisor、seL4、NOVA、P4 Pike、Minix、μC/OS-ii、ADEOS、EPOC、EKA1、EROS、Mac OSWindows NT、Micro Empix、TI-RTOS、WarpOS、嵌入式Linux、Windows Embedded、PSOS、VxWorksZircon等。

    从理论上来讲,一个操作系统既可以采用微内核架构,也可以采用宏内核架构,只要有开发人员愿意进行产品研发。譬如,早期的Windows NT、Mac OS等采用微内核架构,后面因为性能问题将用户空间的一部分功能移到内核空间,构成一个混合内核。Linux则采用宏内核架构。

    然而随着计算机技术和操作系统的不断发展,微内核和宏内核在不同应用场景中还是存在着实际差别。

    7.1 嵌入式系统

    嵌入式系统具有资源相对有限、专用性强、实时性高等特点,因此应用于嵌入式系统的操作系统必须满足系统内核小、支持实时多任务、具有存储区保护功能以及可裁剪等要求。嵌入式操作系统负责嵌入式系统的全部软硬件资源的分配、任务调度,控制和协调并发活动。它必须体现其所在系统的特征,能够通过装卸某些模块来达到系统所要求的功能。

    嵌入式系统的这种需求与微内核操作系统的发展需求相吻合。现代微内核相关技术仍在继续发展和不断完善中,极小化和高IPC性能这两个基本原则仍然是设计和实现决定的驱动力。

    对于嵌入式系统领域,很多系统甚至没有硬盘存储,它们更多地使用微内核操作系统。

    7.2 工控机、PC、服务器

    对于工控机、PC、服务器来说,因为需要操作系统完成的功能很多,处理的任务非常复杂,因而更适合使用宏内核操作系统。

    如果强调实时性,完成较简单功能的工控机也可以采用微内核操作系统,譬如VxWorks等。

    再次说明,从理论上讲,微内核和宏内核操作系统都可以应用于各种场景,只是目前已经研制的各种操作系统所采取的架构导致了它们在具体应用场景中有所侧重。譬如,微内核操作系统也可以运行于一些PC或服务器上。GNU HURD是一个从1990年就开始研制的微内核操作系统,运行于Mach或L4之上,目前从官网看到的最新版本为2019年开发的Debian版本。作为一个微内核操作系统,它不需要重新启动机器就可以开发和测试新的Hurd内核组件,运行自己的内核组件不会干扰其他用户,因此不需要特殊的系统特权。内核扩展的机制在设计上是安全的:不可能将一个用户的更改强加给其他用户,除非系统管理员或授权用户这样做。但是,由于开发人员很少,进展较慢,还没有达到完全成熟好用阶段。(参见GNU HURD: GNU Hurd

    7.3 移动/物联网操作系统

    在移动、物联网操作系统领域,大家一般把相关的操作系统归类为微内核操作系统,譬如应用在智能手机和平板电脑的Android、iOS等(也有人称它们为混合内核操作系统);之前介绍的鸿蒙操作系统,采用Zircon内核的谷歌Fuchsia,这两个微内核操作系统可能在未来万物互联的物联网系统中发挥重要作用。(参见:鸿蒙系统的微内核是什么 _企业头条 - 天眼查

    总之,对于一些专用系统,主要是实时系统、嵌入式系统、物联网系统,微内核的思想更有吸引力。究其原因,主要是因为通常这些系统都不带磁盘,整个系统都必须放在EPROM中,常常受到存储空间的限制,而所需要的服务又比较单一和简单。所以,几乎所有的实时系统、嵌入式系统和物联网系统都采用微内核。当然,微内核也有缺点,将这些服务的提供都放在进程层次上,再通过进程间通信(通常是报文的传递)提供服务,势必增加系统的运行开销,降低了效率。

    与微内核相对应,其他通用式系统由于所需的服务面广而量大,采用宏内核就更为合适。

    8 基于seL4微内核的若干实验研究

    8.1 第三代微内核seL4

    seL4是一个通过形式化验证的、代码被证明是完全正确的操作系统微内核。其实,seL4不仅是一个微内核,它还是一个类似KVM的虚拟化管理程序(hypervisor),可以在它上面运行一个虚拟机。如下图所示,seL4支持在虚拟机中运行其他Linux操作系统。

                                            图4 基于seL4的虚拟化技术

    8.2 实验1:基于中标麒麟操作系统V7.0搭建seL4编译和测试环境

    实验目的:本实验是为研究如何搭建和使用seL4系统。

    实验环境:在搭建seL4编译和测试环境时,选取装有《中标麒麟操作系统V7.0》操作系统的x86机器两台,一台用于编译seL4,另一台用于测试seL4。

    实验步骤:

    编译环境搭建步骤如下:

    (a)搭建编译依赖

    yum install protobuf-compiler protobuf python2-protobuf

    yum install qemu-kvm libvirt libvirt-client virt-install virt-viewer

    yum install centos-release-scl scl-utils-build -y

    yum install devtoolset-8-toolchain -y

    yum install make automake gcc gcc-c++ kernel-devel

    yum install python3-devel

    pip3 install --user setuptools

    pip3 install --user sel4-deps

    pip3 install --user camkes-deps

    yum install ghc cabal-install

    yum install openssl-devel

    yum install qemu-system-x86

    yum install nanopb

    yum install -y gcc gcc-c++ make automake

    yum install ninja-build

    yum install python3

    yum install python2

    pip3 install future

    pip3 install Jinja2

    pip3 install tempita

    pip3 install future

    pip3 install templating

    pip3 install six

    pip3 install ply

    pip3 install protobuf grpcio-tools

    (b)升级cmake版本

    wget https://cmake.org/files/v3.17/cmake-3.17.0.tar.gz

    tar -zxvf cmake-3.17.0.tar.gz

    cd cmake-3.17.0

    ./bootstrap --parallel=16

    gmake -j 16

    gmake install

    (c)编译sel4源码

    mkdir sel4-tutorials-manifest

    cd sel4-tutorials-manifest

    repo init -u https://github.com/SEL4PROJ/sel4-tutorials-manifest

    repo sync

    ./init --plat pc99 --tut hello-world  --solution

    cd hello-world_build

    ninja -j 8

    测试环境搭建步骤如下:

    (d)修改启动项

    menuentry 'sel4-hello-world' --class fedora --class gnu-linux --class gnu --class os {

        load_video

        insmod gzio

        insmod part_msdos

        insmod xfs

        set root='hd0,msdos1'

        search --no-floppy --fs-uuid --set=root b83f90f1-65b3-4db3-b19b-ef30ca140513

        echo    'Loading seL4 kernel'

        multiboot / kernel-x86_64-pc99

        echo    'Loading initial module ...'

        module  /hello-world-image-x86_64-pc99

    }

    (e)准备seL4内核和应用镜像

    从编译环境中复制images文件夹中的kernel-x86_64-pc99和hello-world-image-x86_64-pc99文件到测试环境的/boot文件夹下

    (f)重启并选择seL4启动项

    重启,选择“sel4-hello-world”启动项,在串口中出现下图画面

                                            图5 Hello World测试程序输出

    至此,seL4的编译环境和测试环境搭建完毕。为了进一步研究如何修改helloworld程序,可以在编译环境中对/root/sel4-tutorials-manifest/ hello-world/src/main.c文件进行修改,如下图所示:

                                            图6 新Hello World测试源码

    重新回到测试环境中的/root/sel4-tutorials-manifest/hello-world_ build目录,执行ninja clean && ninja -j 8命令,命令执行成功后,把kernel-x86_64-pc99和hello-world-image-x86_64-pc99两个文件复制到测试环境中/boot目录下,重启测试机器,选择“sel4-hello-world”启动项,可以看到修改后的源码输出,如下图所示:

                                           图7 新Hello World测试效果

    8.3 实验2:基于seL4进行进程间通讯

    实验目的:为进一步研究seL4如何使用,需要研究如何在seL4系统下进行进程间通讯。

    实验环境:与实验1相同。

    实验步骤:

    我们写了一个server端和两个client端和CMakeLists.txt文件。

    server.c代码如下图所示:

                                            图8 进程间通讯server源码

    client1端代码如下图所示:

                                            图9 进程间通讯client1源码

    client2端源码如下图所示:

                                            图10 进程间通讯client2源码

    CMakeLists.txt代码如下:

                                            图11 进程间通讯CMake文件

    对上述文件执行cmake . && ninja 命令后,在把images文件夹中的kernel-x86_64-pc99和capdl-loader-image-x86_64-pc99两个文件复制到测试环境中/boot目录下,增加启动项,重启后选择新建启动项,则会在串口中发现如下图所示输出:

                                            图12 进程间测试效果

    8.4 实验3:seL4性能测试实验

    实验目的:为了测试seL4的性能,需要对ipc、irq、schedule、signal、fault、hardware、sync、page_mapping等方面进行性能测试。

    实验环境:与实验1相同。

    实验步骤:

    使用google-benchmark测试工具库,对每一个测试项编写一个测试程序,如下图所示:

                                            图13 性能测试工程树

    针对上述源码,为每一个测试源码编写CMakeLists.txt文件,执行ninja命令成功后,把images文件夹中的kernel-x86_64-pc99和sel4benchapp-image-x86_64-pc99文件复制到测试环境的/boot目录下,增加启动项,重启后选择新增加的启动项。观察串口输出,抓取输出数据起始信息如下图所示:

                                            图14 性能测试原始数据

    对原始数据进行格式化处理后,显示信息如下所示:

                                            图15 性能测试结构化数据

    8.5 实验4:seL4虚拟化实验

    实验目的:为研究如何在sel4上运行Linux。

    实验环境:与实验1 相同。

    实验步骤:

    (a)准备内核

    使用中标麒麟安全操作系统V7.0系统中自带内核源码,对内核进行如下修改:

    CONFIG_X86_32=y

    CONFIG_X86=y

    CONFIG_X86_32_SMP=n

    CONFIG_SMP=n

    CONFIG_NOHIGHMEM=y

    CONFIG_PCI_MSI=n

    CONFIG_X86_UP_APIC=n

    CONFIG_SUSPEND=n

    CONFIG_HIBERNATION=n

    CONFIG_PM=n

    CONFIG_ACPI=n

    CONFIG_VIRTIO=y

    CONFIG_VIRTIO_PCI=y

    CONFIG_VIRTIO_NET=y

    (b)准备initrd

    使用中标麒麟安全操作系统V7.0系统中自带initrd

    (c)编写camkes文件生成虚拟机

    import <VM/vm.camkes>;

    #include <configurations/vm.h>

    #define VM_GUEST_CMDLINE "earlyprintk=ttyS0,115200 console=tty0 console=ttyS0,115200 i8042.nokbd=y i8042.nomux=y \

    i8042.noaux=y io_delay=udelay noisapnp pci=nomsi debug root=/dev/mem"

    component Init0 {

        VM_INIT_DEF()

    }

    assembly {

        composition {

            VM_COMPOSITION_DEF()

            VM_PER_VM_COMP_DEF(0)

        }

        configuration {

            VM_CONFIGURATION_DEF()

            VM_PER_VM_CONFIG_DEF(0)

            vm0.simple_untyped23_pool = 20;

            vm0.heap_size = 0x2000000;

            vm0.guest_ram_mb = 128;

            vm0.kernel_cmdline = VM_GUEST_CMDLINE;

            vm0.kernel_image = "bzimage";

            vm0.kernel_relocs = "bzimage";

            vm0.initrd_image = "rootfs.cpio";

            vm0.iospace_domain = 0x0f;

        }

    }

    (d)编写CMake文件生成sel4镜像

    include(${SEL4_TUTORIALS_DIR}/settings.cmake)

    sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR})

    cmake_minimum_required(VERSION 3.8.2)

    project(vm-app C ASM)

    include(ExternalProject)

    find_package(camkes-vm REQUIRED)

    include(${CAMKES_VM_SETTINGS_PATH})

    camkes_x86_vm_setup_x86_vm_environment()

    include(${CAMKES_VM_HELPERS_PATH})

    find_package(camkes-vm-linux REQUIRED)

    include(${CAMKES_VM_LINUX_HELPERS_PATH})

    include(simulation)

    GenerateSimulateScript()

    DeclareCAmkESVM(Init0)

    GetDefaultLinuxKernelFile(default_kernel_file)

    GetDefaultLinuxRootfsFile(default_rootfs_file)

    DecompressLinuxKernel(extract_linux_kernel decompressed_kernel ${default_kernel _file})

    AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel)

    AddToFileServer("rootfs.cpio" ${default_rootfs_file})

    DeclareCAmkESVMRootServer(vm_tutorial.camkes)

    GenerateCAmkESRootserver()

    (e)测试与验证

    执行ninja命令成功后,把images文件夹中的kernel-x86_64-pc99和capdl-loader-image-x86_64-pc99文件复制到测试环境的/boot目录下,增加启动项,重启后选择新增加的启动项。观察串口输出,可看到如下图所示信息:

                                            图16 虚拟机启动界面

    8.6 实验5:seL4与Linux性能对比测试

    seL4官方提供了一个性能测试工具sel4bench,直接编译运行就可以得到测试结果。我们仔细研究了sel4bench,然后花时间将每个测试用例移植到了Linux平台下,从而得出了Linux环境下的测试结果。

    1. 内核版本:

    seL4内核版本: 11.0.0-dev

    Linux发行版本CentOS Linux release 8.2.2004 (Core),Linux内核版本4.18.0-193.19.1.el8_2.x86_64

    1. 测试工具:

    seL4微内核环境:使用seL4官方提供的测试工具sel4bench

    Linux环境:将seL4官方提供的测试工具sel4bench移植到Linux内核环境

    1. 测试结果(单位ns):

     

    最小时间

    平均时间

    最大时间

     

    Sel4

    Linux

    Sel4

    linux

    Sel4

    linux

    ipc

    128

    2102

    131

    2282

    134

    3121

    irquser

    113869

    15605

    380496

    22724

    646754

    48663

    scheduler

    340

    519

    354

    628

    672

    849

    signal

    187

    5

    214

    48

    337

    126

    fault

    279

    1718

    284

    1734

    291

    1754

    hardware

    167

    58

    180

    205

    390

    7718

    sync

    1763

    1752

    1778

    1966

    1836

    2181

    表1 seL4与Linux性能测试结果

                                             图17 seL4与Linux性能对比测试

    通过以上对比测试,可以看出seL4内核与Linux内核综合性能持平

    d)测试基准单位

    TSCTime Stamp Counter)时间戳计数器的值:从pentium开始,很多80x86微处理器都引入TSC,一个用于时间戳计数器的64位的寄存器,它在每个时钟信号到来时加一。当前使用的CPU主频为2.90GHz2903.998MHz),所以计数器的单位大约是0.34ns

    e)测试原理:

    seL4微内核和Linux内核之间主要做了以下对比测试:

    ipc Benchmarks:进程间通信机制( Inter-Process Communication,IPC)是一项影响内核操作系统整体性能的关键因素。为了评估IPC通信的实时性能, ipc Benchmarks测试用例中通过统计内核IPC通信机制下消息在内核中的时间消耗,用以测试高实时优先级进程的通信延时。

    irquser Benchmarks:中断处理是整个系统中优先级最高的代码,在系统运行过程中,中断程序可以抢占到任意任务级别的代码运行,而且中断也分等级,高级别中断抢占低级别中断。系统实时性是依靠中断机制来保证的,多任务的环境运行基础也是中断机制。所以对于衡量内核性能,最重要的指标就是中断延迟。irquser Benchmarks测试用例用来测试内核的中断延迟。

    scheduler Benchmarks:主要用于统计任务切换时间(task switching time),即系统在两个独立的、处于就绪态并且具有相同或不同优先级的任务之间切换所需要的时间。切换所需的时间主要取决于保存任务上下文所用的数据结构以及操作系统采用的调度算法的效率。产生任务切换的原因可以是资源可得,信号量的获取等。任务切换过程增加了应用程序的额外负荷。CPU的内部寄存器越多,额外负荷就越重。任务切换所需要的时间取决于CPU有多少寄存器要入栈。

    signal Benchmarks:信号量混洗时间是指从一个任务释放信号量到另一个等待该信号量的任务被激活的时间延迟。在操作系统中,通常有许多任务同时竞争某一共享资源,基于信号量的互斥访问保证了任一时刻只有一个任务能够访问公共资源。信号量混洗时间反映了与互斥有关的时间开销,因此也是衡量内核实时性能的一个重要指标。

    fault Benchmarks:异常是可以打断CPU正在运行流程的一些事情,比如外部中断、未定义指令、试图修改只读数据、执行swi指令(中断指令)等。当这些事情发生时,CPU暂停当前的程序,先处理异常事件,然后再继续执行被中断的程序。中断也是异常的一种。fault Benchmarks测试用例用于统计内核处理异常时间消耗。

    hardware Benchmarks:用于统计内核执行空系统调用的时间消耗。

    sync Benchmarks:互斥锁是使用简单的加锁的方法来控制对共享资源的存取。互斥锁只有两种状态,也就是上锁和解锁。可以把互斥锁看作某种意义上的全局变量。在同一时刻只能有一个线程掌握某个互斥上的锁,拥有上锁状态的线程能够对共享资源进行操作。若其他线程希望上锁一个已经上锁了的互斥锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止。互斥锁使得共享资源按序在各个线程中操作。sync Benchmarks使用互斥锁和信号量实现多线程间的同步,统计同步信号发出到所有等待线程接收到同步信号的时间消耗。

    展开全文
  • 基于微内核的虚拟机I/O安全机制
  • 所以今天的重点在微内核,而这个概念我最早是从操作系统那里得知,不过操作系统的微内核和 Dubbo 相关的微内核又不太一样。 Dubbo 的微内核广义上的微内核,而操作系统只是针对内核实现。 我们先看看操作系统的...
    导读这篇文章借着 Dubbo 来说说微内核这种设计思想,不会扯到 Dubbo 某个具体细节实现上,和 Dubbo 强相关的内容会在之后的文章写到。所以今天的重点在微内核,而这个概念我最早是从操作系统那里得知,不过操作系统的微内核和 Dubbo 相关的微内核又不太一样。

    Dubbo 的微内核广义上的微内核,而操作系统只是针对内核实现。

    我们先看看操作系统的微内核。

    操作系统中的微内核

    在维基百科上搜索微内核出现的就是:

    在计算机科学中,微内核(英语:Microkernel,μ-kernel),是一种内核的设计架构,由尽可能精简的程序所组成,以实现一个操作系统所需要的最基本功能,包括了底层的寻址空间管理、线程管理、与进程间通信。

    这个词条归类在操作系统技术下,所以这里的微内核指的就是操作系统的内核设计,与之对应的是宏内核架构。

    Linux 就是宏内核架构。

    操作系统我们都知道它是一个中间层,为我们管理底层的硬件资源,为上层服务提供接口。

    提供进程管理、内存管理、文件系统、进程通信等功能。

    像 Linux 这样的宏内核设计是把这些功能都作为内核来实现,而微内核则仅保留最基础的功能。

    比如就留下进程的管理、内存管理等,把文件管理等功能剥离出去,变成用户空间的独立进程来提供服务。

    来看下这个维基百科上的这个图应该就很清晰了。

    操作系统微内核和Dubbo微内核各自优缺点!操作系统微内核和Dubbo微内核各自优缺点!

    宏内核中的一些功能在微内核架构上都被独立到用户态中,这样内核代码量就少了。

    代码少了潜在的 bug 就少,出了问题也更容易排查。

    系统也就更加稳定,不易奔溃,因为那些服务从内核中移除,在用户空间运行着,如果出了故障,内核重启这个服务就好了,不会像之前那样整个内核 GG。

    拿显卡驱动来说,出问题就蓝屏,这要是微内核设计就可以重启显卡驱动。

    听起来好像微内核很好啊?并不是,接下来就说说微内核的缺点。

    首先是性能问题。

    因为很多功能作为独立进程放到用户空间运行了,所以宏内核时的函数调用就变成了进程间调用,涉及进程间的通信,还会伴随着内核态和用户态的来回切换,我们知道这种上下文切换时比较耗时的。

    这性能的问题就有点大了。

    然后微内核设计没那么简单,想要灵巧、减少耦合、提高可移植性就需要好好的设计,按照林纳斯的话来说:“如果 GNU 内核(微内核架构)早在去年春天完成了,我压根不会开始我的项目(Lniux)。”

    GNU Hurd 采用微内核架构,设计过于精巧,研发速度缓慢,性能长期无法提升。

    当年林纳斯还和 Minix 的作者安德鲁,对操作系统的宏内核和微内核的好坏进行了一波网络口水战。

    我们来回顾一下那段历史,挺有意思的。

    因为 AT&T 把 Unix 商业化了,大学不能免费使用 Unix,身为大学教授的安德鲁为了教学自己搞了个操作系统,即 Minix。

    操作系统微内核和Dubbo微内核各自优缺点!操作系统微内核和Dubbo微内核各自优缺点!

    安德鲁

    当时的学术风潮是微内核架构,把核心功能模块化,划分为几个独立的进程,运行在不同的地址空间提高了代码的可移植和系统的安全性。

    所以 Minix 就是按微内核架构编写的,当然还有上述提到的 GNU Hurd。

    而林纳斯那时候读大学,他祖父送了他一台 Intel 80386,林纳斯也看到了安德鲁的教科书,根据书上的内容写出了 Linux。

    操作系统微内核和Dubbo微内核各自优缺点!操作系统微内核和Dubbo微内核各自优缺点!

    林纳斯

    不过没有按照微内核的设计,而是跟 Unix 一样采用了宏内核架构。

    安德鲁教授看到了 Linux ,然后在 comp.os.Minix 上批评道:宏内核的设计是有害的。

    Linux 内核耦合度太高,完全是为了 Intel 80386 而设计的,处理器架构进化很快的,操作系统应该都具备可移植性。

    安德鲁还提到:都1991年了还用宏内核来设计操作系统,这是一种巨大的退步。

    林纳斯在一天之后进行了反击,他说 Minix 设计上有缺陷,从哲学和美学角度来看微内核确实好,但是你看 GUN Hurd 到现在还没开发出来。

    然后操作系统本来就依靠硬件的特性,所以内核本身不需要过度具备可移植性,应用程序的可移植性才重要,Linux 比 Minix 好移植多了。

    而且 Linux 本来就是为我自己做的,所以契合 80386,如果要移植到别的平台,代码都是开源的(Minix 源码当时得买),想要的人自己做咯。

    安德鲁也做了一波回应:Minix 有局限性是因为我是教授,因为大部分学生都只能在低配的机器上使用,所以系统的硬件需求得足够低,虽然你 Linux 是免费的,但是需要的硬件贵呀。

    其实可以看到,两者并没有对宏内核和微内核的技术细节的进行深入探讨,而是抓住对方的:你这 Minix 代码还要收费,你这 Linux 需要的硬件这么贵来进行“攻击”,所以称之为口水战。

    反正口水战之后双方都没有改变各自的设计,不过林纳斯有引进微内核的思想来改进代码,也改善了可移植性。

    微内核市面上设计成功的有 QNX,黑莓手机就是用这个操作系统,车用市场也几乎都用 QNX 系统。

    这手机很多年前我用过,当时觉得有点东西的。

    宏内核的话就提个 Linux ,足够了。

    两个架构都有成功的产品,所以还是取舍的问题,也没有谁完全压着谁。

    再具体的就不深入了,今天的主角其实是广义上的微内核。

    Dubbo 中的微内核

    Dubbo 的微内核是广义上的,它的思想是:核心系统+插件。

    操作系统微内核和Dubbo微内核各自优缺点!操作系统微内核和Dubbo微内核各自优缺点!

    这个微内核说白了就是把不变的功能抽象出来称为核心,把变动的功能作为插件来扩展,符合开闭原则,更容易扩展、维护。

    小霸王游戏机大家都应该玩过,它的设计就可以认为是个微内核设计。

     

    机体本身作为核心系统,游戏片就是插件。

    我们想玩哪个游戏就插哪个游戏片,简单便捷,不影响机体本身。

    假设不把游戏片抽象成插件式,那是不是就难搞了?换个游戏就成为难题了。

    所以微内核架构的本质就是将变化的部分抽象成插件,使得可以快速简便地满足各种需求又不影响整体的稳定性。

    这就是微内核架构的精髓。

    这里再扣个细节,较个真(就是我个人的一点想法)。

    Mark Richards 在 《Software Architecture Patterns》的微内核章节里面提到

    The core system of the microkernel architecture pattern traditionally contains only the minimal functionality required to make the system operational.

    从字面意义来看,Mark 认为核心系统指的是可以独立运行且提供基本功能的最小模块。

    例如 vscode、idea、chrome 等设计就符合 Mark 认为的核心设计,核心系统提供基础必备的功能,可以独立运行。

    像 vscode 核心就是编辑器,没有插件也可以独立运行,然后又有丰富的插件,来满足一些特殊需求,扩展核心系统的功能。

    这里可能会让人产生误导,认为核心必须是能让系统运行的最小功能模块。

    我认为核心不一定需要独立运行且提供基础功能,能让系统运行的最小组织模块也是核心。

    两个说法的差别在于:只有核心的话系统能否正常的运行。

    vscode 没有插件照样能运行,能提供基本功能,而小霸王游戏机没有游戏片那运行个寂寞,玩个球。

    但是小霸王这种难道就不算微内核了嘛?

    就我个人而言,把变与不变区分出来,把变化封装成插件就称为微内核设计。

    像 Dubbo 能支持很多协议、各种负载均衡的扩展、集群的扩展等等,它自身的一些功能也是通过扩展点实现的,没有插件也跑不了。

    这样的内核就像胶水,把各个插件结合起来最终提供服务,没有插件这个系统就没什么意义。

    所以我认为核心系统不一定需要能独立运行,能让系统运行的最小组织模块也是核心。。

    因此我觉得 Mark 说的不太准确,容易产生误导。

    当然这是文字上面的抠细节,核心概念都是一致的:抽象出核心,剥离变化为插件。

    微内核设计的好处

    这里的微内核指的是广义的微内核。

    作为一个框架或者软件,扩展性非常的重要。

    因为一个框架、一个软件的使用者千千万,不同的人有不同的需求。

    身为框架的维护者、软件的开发者你有精力和能力满足所有用户的需求?

    做梦,不存在的。

    来感受一下?

    操作系统微内核和Dubbo微内核各自优缺点!操作系统微内核和Dubbo微内核各自优缺点!

    所以做一个框架或者软件,想要让更多人使用,不仅自身提供的功能要全、性能要好、使用要简单,让用户 DIY,做各种定制化也非常的关键!

    Dubbo 的成功其实就离不开它的微内核设计,定制化开发在很多场景都要用到,毕竟都得稍加改造一番来满足自己公司的一些特殊需求。

    当然也不是什么都要微内核

    微内核看起来是很方便,但是设计起来就不方便了。

    需要精心的设计,抽象出各种扩展点。

    除了本身的功能还需要管理插件的生命周期、插件如何连接、如何通信等。

    有些还需要做沙箱隔离,防止插件污染整个系统等等,本来的内部函数调用变成了插件间的通信,反正设计起来是复杂了。

    一般微内核适合用在框架的设计上,或者一些规则引擎的设计,只有复杂的会有很多变化的需求场景才需要用到微内核。

    像一般简单的项目,本来就一条直道走到底的那种就算了,不要瞎操作,等下秀折了腿。

    最后

    微内核其实就是一种架构思想,可以是框架层面的,也可以细化到某个模块的设计。

    归根结底就是把变化封装成插件,可插拔,拥抱变化。

    当然今天也提到了操作系统的微内核,这个和广义上的微内核还是不太一样的。

    至于 Dubbo 的微内核就离不开它的 SPI,之后文章会深入写一波,等我哈。更多Linux资讯请查看:https://www.linuxprobe.com

    展开全文
  • 闪闪发光:Rust Rust中的一个微内核
  • ARM平台多进程微内核嵌入式操作系统Ymodem下载功能设计与实现.pdf
  • 基于微内核的操作系统PARAS的研究与开发,用于C-DAC PARAM系列超级计算机。
  • Unix sel4 微内核源码

    2018-05-15 17:29:26
    但是seL4的性能可以与当今性能最好的微内核相比。 作为微内核,seL4为应用程序提供少量的服务,如创建和管理虚拟内存地址空间的抽象,线程和进程间通信IPC。这么少的服务靠8700行C代码搞定。seL4是高性能的L4微内核...
  • 什么是微内核架构

    千次阅读 2021-03-09 00:28:12
    什么是微内核架构相信大家都听说过微内核架构,也或多或少做过一些类似于微内核架构的设计,为了可以更好的设计出微内核的架构,我们了解下什么是微内核架构。说到微内核架构,大家首先会想到的是Ecl...

    什么是微内核架构

    相信大家都听说过微内核架构,也或多或少做过一些类似于微内核架构的设计,为了可以更好的设计出微内核的架构,我们了解下什么是微内核架构。

    说到微内核架构,大家首先会想到的是Eclips、IDEA、OSGI、Spring Plugin、SPI等,这些都是我们熟知的微内核架构。有了微内核架构,我们可以更好的定制和控制流程,所以微内核架构的设计思想经常在做配置化中台项目的方案中出现的。

    微内核架构实现主要是插件化思想(Plug-in),是一套插件体系,最早的插件化方法是应用在操作系统之上,久而久之就有了微内核设计这一思想。

    了解微内核,需要先了解这个“内核”。

    在操作系统中,内核围绕于操作系统的核心功能,比如时钟中断、进程创建与销毁、进程调度、进程间通信等内核态的动作。而文件系统、内存管理、设备驱动等都被视为非内核能力,这部分会被放在用户态空间。

    微内核是相对于宏内核而言,宏内核包含了很多的底层程序功能,做的事情非常多,而且不是可拔插的,修改任意一个功能点,都需要整个程序联动,而且有可能引入一个bug,导致整个内核不可用,类似于一个功能复杂的单体系统,每次变更和交付成本都非常高,风险也非常大。

    而微内核只围绕于核心功能设计,他的功能实现都是相互独立的,其他非核心功能是通过用户态的独立进程以插件的方式加入进来的,微内核引擎负责管理进程、调度进程、进程之间通信。某一个功能出现问题时,由于其是独立的进程,不会对其他进程产生影响,也不会导致内核不可用。

    微内核中,多个进程协调通信,需要进行系统调用,系统调用需要切换堆栈及保护进程现场,过程比较耗时。宏内核(也就是用户态)中,是通过函数调用完成各个模块之间合作,所以宏内核较微内核效率更高。

    通过操作系统微内核概念,可以类比到业务系统。一个系统,特别是经过微服务拆分之后的系统,都会服务于某个“内核”,多个核心功能通过微服务的方式拆分,服务之间通过通信交换数据。通过微内核解决了快速交付问题,实现了代码隔离,控制风险点的目的。

    而考虑到扩展性,我们需要定义出内核的骨架,并开放出plugin,以实现个性化扩展。这样的微内核架构,我们可以便于定制,改动小,进而实现热更新,这也是微内核架构的主要价值。

    微内核架构设计

    在微内核架构中有两个核心组件:系统内核、插件化组件。

    系统内核:主要解决的是内核的核心功能,比如插件的注册与管理、插件生命周期管理、插件之间通信、插件的热加载与替换。

    结构如下:

    基于微内核的插件化设计,我们可以实现组件隔离,每个插件可以以独立jar包或独立进程运行,这些插件组件进程可以独立部署在分布式网络上,实现水平扩展,某种程度就像我们的微服务治理体系,有独立部署的微服务进程,也有中心治理的注册中心与配置中心。

    在操作系统中,微内核与宏内核通信方式上有如下区别:

    微内核架构下,组件之间的通信也是基于消息的,比如每个组件对于消息处理有两个能力:收(receive)、发(send)。

    那两个进程之间通信,是否需要一个三方中介呢?比如这样:

    在操作系统中,消息的通信是基于内核转发的,也就是我们经常听说的消息总线架构,内核负责协调各个进程的通信,比如进程A想要发送消息给进程B,需要知道B对应的内存地址。进程向内核发送消息,内核再将消息发送给对应的接收进程,这就是一个总线通信过程。

    在很多微内核架构设计实现上,组件之间都可以通过EventBus实现Plug-in之间的解耦,也就是借鉴了总线的设计。

    在微服务架构的通信实现上,在SOA时代,有类似于消息总线的概念。但微服务是进程之间的直接调用,没有了这个所谓的总线。

    但是如果引入了一个中心化的服务注册与发现中心,就可能也会有个所谓的内核中转:

    在插件化系统中,组件之间不直接通信,而是借助于一个中心化的内核系统进行转发。这种设计思想非常类似于操作系统的内核转发实现,插件之间隔离、透明。某个组件下线或替换,其他组件不需要感知。

    这样的架构会存在于一些其他的问题。首先,这个中心化的转发中介变成了单点,其可用性严重影响了整个系统的可用性。当中心化系统变成单点转发,就存在对应的性能问题。

    对于远程进程调用的性能优化,我们可以想到这几点:

    1. 采用高性能的二进制协议代替http1.x协议,因为http1.1的文本协议性能较差;

    2. 采用类似于零拷贝机制,实现快速网络包转发,而不需要做内核态与用户态的转换;

    3. 引入好的网络硬件,比如RDMA;好的协议,如UDP、QUIC等;

    4. 选择不同的通信方式,比如RPC的、Pub/Sub的、无序ACK的、单工/双工通信的等;

    为了处理这么多协议的转发,内核系统需要具备Adapter以实现对于众多协议的解析与转发,比如引入多个filter来支持不同的协议,但是他将变得越来越复杂。

    还有一种思路是,内核服务只支持一种协议,各个插件之间也基于这个协议通信,协议的适配与转换由各个组件自己做就可以。

    其实很多人会想到,这个中心化的内核组件的消息转发不就是类似于一个MQ系统的Broker吗?而那种独立处理通信协议的组件不就类似于Mesh设计吗?

    没错,前一种类似于类似于broker,后一种类似于service mesh或agent思想。功能上是一样的,只是处理逻辑上有些差异。

    broker是集中式的,所有组件通过broker进行消息的收发,涉及到注册与发现机制。mesh是基于服务的注册与发现,消息发送需要找到对方的agent,再实现两个agent之间的通信。

    broker方案设计核心在于,broker需要管理注册的服务、路由的管理、数据的采集等这些核心功能,类似于微内核的内核本身理念一样。如果要扩展整个微内核架构能力,需要编写独立的service,之后和broker对接,在broker接收消息,处理完毕后发送消息。

    那中心的broker负载太高如何扩容呢?因为broker本身具有服务调用的数据采集能力,所以可以从这里采集,作为扩缩容的参考,经过分析后,可以调用k8s的api实现pod的扩缩容了。

    我们可以发现,这套围绕于内核的核心设计以及扩展service的思想非常的云原生,比如上层业务系统想要调用存储服务,微内核系统可以对外提供一个消息存储的api,而这套api可以按需扩展是基于redis、还是tair或是其他kv,为服务标准化和可替代性提供了很好的基础,对上云操作非常友好,也就体现了云原生的灵活性。

    中心化转发和点对点发送,两个方案各有优缺点,架构就是一个取舍的过程,我们需要结合自己系统的特点和体量决定选择合适的方案。

    总结

    微内核架构对于我们做微服务设计,或是偏中台、平台系统设计提供了非常好的参考建议,比如对于微服务边界的划分,我们完全可以参考操作系统的设计,经过几十年的发展,其设计之精妙已经被验证了,非常稳定,功能划分也非常合理。

    展开全文
  • 什么是微内核,看这一篇就够了

    千次阅读 多人点赞 2021-07-08 10:25:24
    微内核是将服务转移到进程上的一种内核模式。宏内核是一种传统的内核结构,它将进程管理,内存管理等各项服务功能都放到内核中去,通常用在通用式的内核上,如unix,linux等。 两个系统的内核是通过进程的创建FORK...
  • [Kernel]微内核、单内核 一、从应用层面直观说明采用各种内核的系统 微内核:华为鸿蒙系统、Windows系统、塞班系统 单内核:Unix、Linux、FreeBSD、安卓系统 二、各自的特点 这里两种起始类似与RISC和CISC的比较,...
  • 微内核与宏内核比较

    千次阅读 2021-05-11 01:19:08
    微内核与宏内核比较内核体系结构---微内核与宏内核比较内核按照体系结构分为两类:微内核(microkernel)与宏内核(macrokernel). 微内核的系统有WindowNT,Minix,Mach,etc.宏内核的系统有Unix,Linux,etc.通过比较Minix和...
  • 本文为你介绍微内核操作系统的定义,及其采用微内核设计的操作系统都有哪些?同时附有 Linux 是一个单内核结构的介绍,不过 Linux 还吸收了微内核的优点,所以系统表现相当的出色。微内核如今非常受关注,起因是华为...
  • 1980-2000年间,microkernel操作系统被广泛研究,目的是解决macrokernel的巨大,不安全,更新困难等问题,但是,由于性能上的原因,微内核系统没有发展起来。最近cpu性能已经足够强大,微内核系统又逐渐发展,例如...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 72,418
精华内容 28,967
关键字:

微内核

友情链接: rle.rar