当前位置: 首页 > Linux

【转】微内核OS史上最透彻的文章(编辑、排版)

时间:2023-04-07 00:14:52 Linux

本文由知名博主Dog250原创,Linux代码阅读领域投稿。《有关微内核OS史上最透彻一篇 - 写于华为鸿蒙发布一周之际》编辑自腾讯云1、微内核和宏内核场景分析。我将使用常见的read调用来读取文件,并以Minix为例来展示它的行为:这里需要说明的是,上述场景的每一步似乎都在进行进程间通信(IPC)。事实上,这就是微内核如此特别的原因。为了让系统的核心服务进程FS、MM等更好地服务于各个用户进程,在这些进程内部保存了系统中所有进程的服务进程相关的当前信息的快照。FS进程请求SYS进程将从磁盘读取的内容复制到用户进程P的缓冲区中,这一步不涉及用户进程,所以FS进程至少要知道用户进程P的内存信息元数据,这样内核就可以活跃的SYS进程完成复制操作。其实可以这样理解,在微内核中,FS、MM等服务进程的逻辑和快照数据在宏内核中对应于内核本身,只是它们的访问方式不同:宏内核访问的是具体的逻辑和数据。微内核通过IPC(进程间通信)访问特定的逻辑和数据。作为对比,我们来看看宏内核linux是如何完成等同于上述IPC场景的操作步骤的:貌似也是读取文件,微内核只是将宏内核的垂直通信换成了水平通信。不过,在这一纵一横的背后,却隐藏着天壤之别。垂直通信是发生的实际服务调用,物理通信。横向沟通是点对点的沟通,即逻辑沟通。【这也是影响性能的核心因素】采用横向通信方案固然会损害性能,但得到的更多。与OSI和TCP/IP分层模型相比,以上说辞再熟悉不过了。如果只是介绍微内核的运行原理和流程,我觉得到这里就结束了,是时候愉快的看代码了。然而,在现实中,微内核与宏内核并不平等。我们不使用它或接受它。除了商业和生态因素造成的先入为主的观念外,还有一个更重要的因素,那就是性能。2.性能比较微内核性能太差了!大家都认为微内核性能差是IPC开销大,系统调用开销大??造成的。当然,我也这么认为。但这只是事情的一方面,事情还有另一方面。微内核的话题无非就是:精简内核,只保留最核心的,其他的都交给用户态。模块化、可插拔、易于扩展。安全性,相互隔离,相互独立,可以采用不同的安全策略。数学证明。性能……网上搜了一大堆题目,大部分都是玄学公式,这里就不想再复制粘贴了。接下来,我将仅从性能方面对微内核进行定性评测。另外,我试图粉饰微内核的性能。A。通信模型当涉及到对等层的逻辑通信时,仍然需要在垂直物理通信中实现。我还是用自己比较熟悉的网络方面来打个比方。典型的TCP/IP通信模型如下:对于Minix微内核的读取场景,几乎与TCP/IP模型相同。在水平点对点IPC下,真正落地的是垂直传播。上述IPC横向逻辑通信流程对应的纵向实际流程如下图所示:只要看一眼这张图,第一感觉就是这太繁琐了!宏内核中的一次系统调用,微内核中的IPC需要12次系统调用,只重复了6对send/receive!这样的设计性能显然不行,那有什么意义呢?这些事会晚一些讨论。对于微内核来说,只需要send和receive两个系统调用就够了,所有的系统功能都可以通过send/receive这两个系统调用封装IPC消息来完成。相应的,像FS、MM这样的服务进程,和普通的web服务器守护进程一样,只是在一个大循环中等待receive。极简主义的缩影,不是吗?这让我们想起了RISC处理器。看他们的汇编指令,内存访问和寻址只有load/store两条指令,也是极简主义的典范。极简就是极简,但是请看上面那个繁琐的过程,在宏内核中一个read系统调用,在Minix微内核中需要整整12个系统调用才能完成。回到上面的话题,性能在哪里?效率在哪里?重点是什么?这是备受诟病的微内核的核心。确实,对于一个纯传统的IPC方案来说,这么多的系统调用,开销是非常可观的。不过,通过以太网的发展史,我们或许可以看到曙光。b.共享总线和交换模式再来看看早期的共享总线以太网:【注】工作方式:CSMA/CD(CarrierSenseMultipleAccess/ConflictDetection)listenbeforesending,listenwhilesending,conflictstops,Randomlydelayedretransmissions。再对比一下宏内核:可能我们对宏内核太熟悉了,我们天天用Linux内核不是吗?这导致我们可能看不到其他可能性。这个事实蒙蔽了我们的双眼,让我们看不到宏核实际上存在很大的问题,比如多核的不可扩展性。【当然,Linux内核在多核扩展性方面不断优化,这无可厚非,但一直没有wow的解决方案...】宏内核缺少访问共享资源的有序仲裁机制,所以同步开销会很大。最直接的后果是宏内核无法随着处理器内核的增加而扩展。这种情况与早期的以太网多么相似,“以太网的性能随着连接到共享总线上的计算机数量的增加而急剧下降”。所有使用内核服务的进程都在它们自己的隔离上下文中访问底层共享资源(现代操作系统之所以现代的原因),这是没有仲裁的来源。说到以太网,当事情发展到交换以太网时,问题就解决了,因为冲突域塌陷到交换机的背板总线上,作为具有二层逻辑处理能力的交换机,可以进行必要的资源仲裁,例如,排队和队列调度实现数据包的存储和转发:数据包的有序排队代替了对总线的无序竞争,从而避免了冲突。我们看看微内核,这有多么相似:我们回过头来想一想以太网演进到交换以太网的时候发生了什么。面对交换式以太网,肯定有人会质疑,原来数据包可以通过单线直接飞到目的地,现在却要经过交换机,通过逻辑处理多了这么多步骤开关,怎么能和曾经共享公交的时候的一条线路相比呢?怀疑论者显然忽略了CSMA/CD的开销。与CSMA/CD的开销相比,交换机的处理开销从中减去,最终转化为收益。【从那以后交换式以太网就飞起来了,现在10G以太网是标配】类比以太网的发展史,如果我们考虑宏内核在多核处理器上的乱序同步开销,增加一个仲裁功能的服务流程已经大大减少甚至消失。是不是有一丝释然?有了switch之后,人家就忘了CSMA/CD(虽然还是要考试),那么几年后,是不是也忘了spinlock【冲突原地等待】?C。用户态协议栈其实我们在使用宏内核的时候,并不是不理解特殊进程处理特殊事情的重要性,而是这种感觉比较自发的来,并没有形成书面的方法论。一个典型的例子就是近几年非常流行的Linux用户态协议栈。为什么要构建用户态协议栈【权限-内核资源空间-并发】,很明显是因为内核协议栈的性能低下。用户态协议栈可以专用于内核,进程上下文可以全面掌握数据包接收逻辑的全过程,更便于仲裁和协作。如果把用户态协议栈抽象成一个服务,这是否符合微内核的思想?另外,除了协议栈,很多其他的逻辑也被移到了用户态,而在内核态本身,中断也越来越线程化,从而统一参与内核的调度。微内核的思想一直在背后发挥作用。3、发展趋势本来微内核的性能是弱项,结果我说的好像是它的优势,有点不雅。但其实我表达的更多是微内核所展现的一种潜力。从多核扩展性的角度来看,多核平台无疑拥有更好的微内核设计,服务进程的仲裁让应用程序可以在多核平台上无锁运行。A。性能和可扩展性之争不过不管怎样,我承认性能确实是微内核的软肋,尤其是Minix的性能确实不好,但这也意味着微内核可以着重优化性能的软肋。业界公认的性能更好的微内核当属QNX,广泛部署在黑莓手机和汽车上。时间和存在可以证明它信守诺言。在UNIX的悠久历史中,一开始的系统是基于微内核思想的。例如,最初的UNIX系统会有一个swapper进程,负责调度和切换。直到现在,我们仍然可以在UNIX/Linux中找到一个编号为0的swapper/idle进程,虽然它早已淹没在宏内核中,无法再被调度和交换。说到微内核的性能,我觉得经过30多年的发展,微内核和宏内核的性能差距已经大大缩小了。发展的历史从未停止过:微内核和宏内核。跨平台Java语言和C语言。跨平台语言Java和跨语言平台.NET。解释脚本Python和C语言。CISC体系结构和RISC体系结构。……但无一例外,到头来谁也敌不过谁,利益必然要付出代价,大多数纷争最终还是趋于一致。硬件技术的发展往往滞后于软件技术的发展,但硬件技术总是在发展。这一时期,软件技术常常陷入两个概念的争论之中,稍有停滞。最终,硬件技术赶上并弥补了软件性能。缺陷。甚至硬件也可以对软件的需求做出特殊的支持。软件提出需求,硬件实现需求。如果微内核在理论上证明真的很好,只有IPC是瓶颈,直接从硬件开始优化不是更好吗?我觉得QNX和鸿蒙的设计也应该这样考虑。软件和硬件的统一支持,我认为微内核和宏内核最终会有某种融合。我说的不是Windows作为混合内核的马赛克融合,而是熔炉的融合。具体到微内核性能差的根本原因,再来说说IPC优化。b.IPC优化如果实现最基本最简单的IPC,那么内存拷贝就够了。这通常是0.1到1.0的方法。最重要的是让系统先跑起来,完成比完美更重要。【GNUHurd内核的失败是因为Stallman过于理想化,追求完美……反例是Linus,追求完美。】随着硬件技术的发展和系统性能要求的不断提高,IPC必须不断优化。内存复制已经不适用了,共享内存更好。最终可以直接使用硬件的某种机制,比如寄存器,DMA等机制来帮助实现IPC。如果有硬件机制直接提供IPC支持,问题就迎刃而解了。这个过程和sendfile/splice系统调用的设计过程很相似。sendfile/splice的设计____首先Web服务器需要将文件拷贝到Web服务器的内部缓冲区,然后再将缓冲区拷贝到用户的socket中。这与传统的IPC方案非常相似。____然而,随着HTTP逐渐在互联网上占据主导地位,几乎每台Linux服务器都部署了Web服务器,谁能承受两份的瓶颈,于是sendfile呼之欲出。sendfile只是提供了一个外部句柄,真正的数据不需要复制到Web服务器的缓冲区中。通过这个句柄,数据可以直接从文件传递到套接字。____用的人多了,需求有了,问题自然就解决了,从根本上解决了。微内核的IPC也会这样。但是,目前微内核上还没有通用的IPC机制。我相信QNX有优化的IPC,但是不够通用。Android系统的Binder足够通用,还不错,但它并不针对微内核。真希望看看鸿蒙是怎么优化的。最后,我想说一些有趣但人们不太关注的事情。内核态访问空指针会导致系统崩溃吗?不是!只要内核不想恐慌,它就不会恐慌。只要错误没有大到影响硬件状态,系统就不会无条件崩溃。内核之所以出现panic(或者蓝屏),是因为它认为自己是最安全的。正如用户模式可以捕获SEGV信号一样,内核仍然可以捕获空指针访问。然后恢复。前提是你要保证即使出现空指针错误,系统也是稳定的,即没有数据结构被破坏。而这在宏内核中是很难保证的,因为一切都是在一起的。在微内核中,事情就简单多了。首先内核小,出问题的概率自然小。即使出现问题,也很容易知道如何在不损坏其他结构的情况下进行恢复;其次,很多重要的数据结构和逻辑都在用户态的服务进程中,比如文件系统、网络协议栈,甚至驱动程序,这种服务进程都有自己独立的地址空间,即使出现严重问题,它不会污染操作系统的其他部分。Linux改成微内核有多难?困难,但并非不可能。首先,需要改变Linux特有的代码和数据的地址空间结构。说到底就是把它们映射到用户态空间,给它们一组独立的页表。其次,给他们分配task_t,处理调度。最后,最难的是调用方式,也就是说需要手动把函数调用改成IPC,让人感觉还是基于Minix改的比较好。把Linux的好代码移植到Linux上??微内核是不是因为性能不好而名不见经传?我认为这与Linux内核有很大关系。Linux内核太有名了,几乎所有人都认为作为操作系统内核,应该长得像Linux内核。这与Linux内核的开源是分不开的。除了Linux内核之外,很难看到其他开源的流行内核。作为一个遵循POSIX的类UNIX系统,QNX本身就是一个微内核。如果QNX出现在1990i并且是开源的,那么大家眼中的操作系统内核应该就是微内核了。任何事情,只要你说多了,就是对的。总结文章终于写完了。本来想就此结束,但还是想说点心里话。正如我一开始所说的,我希望通过这篇文章的东西给大家带来一些技术。的确,我为此在文章中添加了源代码分析。希望真正把技术讲解清楚,但毕竟这只是一篇文章,不能面面俱到,但即便如此,我还是希望这篇文章至少能作为一篇关于微内核的科普文章,我很高兴。本文以鸿蒙操作系统作为介绍,但仅作介绍。鸿蒙系统的真面目我没有见过,所以不做过多猜测。我没有参与我没有看到的事情。某物。鸿蒙一出来,我发现网上精通操作系统设计开发的专家多得是。原来大家以前都是龙,不用的。现在他们已经变成了天空中的巨龙。真的很心疼华为。当年招人的时候,那么多高手,都化名坤,叫坤。潜在北冥没有接电话。现在一张PPT让他们集体化为鸟,一怒之下飞翔,改名为鹏。...操作系统这门学科即使在计算机科学界也算不上热门,因为它太低级、太复杂、太枯燥,而且学术化、老套。没有漂亮的产品妹子来跟你聊需求,也没有额外的课。下班后,大家一起去喝啤酒,喝串烧。更多的时候,你会半夜在家自己调试或者思考。很难出成果,意味着加薪周期会更长。研发周期长,往往以两年为一个单位,这不符合BAT等互联网大公司每年考核两次的快速迭代、小步走的理念,意味着你甚至可能无法保持你的工作。多年不变的坚实架构,昭示着操作系统领域已经没有新的东西可做。就像TCP/IP协议栈一样,万年不变的底层架构,显然让你的职业生涯没有多少拥抱变化的机会,这显然与互联网的理念背道而驰。说白了,很多人对此不感兴趣。鸿蒙发布后,突然发现很多人都是操作系统专家。我想这是因为华为的火爆,而不是鸿蒙操作系统本身,因为这个操作系统从Windows95和WindowsXP开始就没有火过。不信你回家问问你的家人,除了Windows95/XP,你还听说过哪个划时代的操作系统。最后,如果你要批评我站队华为,那我先给你看看如何在鸿蒙操作系统上写helloworld。反正我没见过。当我看到它时,如果它真的不是人们想要的,我会和你一起喷。你不能打架,但你仍然有办法捉弄人。