现代体系结构上的unix系统 内核程序员的smp和caching技术_操作系统 - 操作系统的结构...

与现代操作系统一样大,复杂的系统,如果要正常运行并易于修改,则必须进行精心设计。一种常见的方法是将任务划分为小的组件或模块,而不是只有一个系统。这些模块中的每一个都应该是系统中定义明确的部分,并具有经过仔细定义的接口和功能。在构造程序时,可以使用类似的方法:不是将所有代码都放在main()函数中,而是将逻辑分成多个函数,清楚地阐明参数和返回值,然后从main()调用这些函数。

接下来,我们将讨论这些组件是怎么样互联并融合进内核的。

单体结构

组织操作系统最简单的结构是没有结构。也就是说,将内核的所有功能放到一个在单个地址空间中运行的单个静态二进制文件中。这种方法(称为单体结构)是设计操作系统的常用技术。

这种有限结构的一个示例是原始UNIX操作系统,它由两个可分离的部分组成:内核和系统程序。内核进一步分为一系列接口和设备驱动程序,随着UNIX的发展,这些接口和设备驱动程序在过去的几年中被添加和扩展。我们可以将传统的UNIX操作系统视为某种程度的分层,如下图所示。系统调用接口之下和物理硬件之上的所有内容都是内核。内核通过系统调用提供文件系统,CPU调度,内存管理和其他操作系统功能。综上所述,这是将大量功能组合到一个地址空间中的功能。

26a2662c252ea723e5abd4a78675512c.png

Linux操作系统基于UNIX,并且结构类似,如下图所示。与内核的系统调用接口进行通信时,应用程序通常使用glibc标准C库。 Linux内核是整体的,因为它完全在单个地址空间中的内核模式下运行,它也具有模块化设计,允许在运行时修改内核。

8332e9764c4124e9b0d13a4a2300e03d.png

尽管单体内核看起来很简单,但是它们很难实现和扩展。但是,单体内核确实具有明显的性能优势:系统调用接口中的开销很小,并且内核内部的通信速度很快。因此,尽管单体内核存在缺点,但它们的速度和效率可以解释为什么我们仍然可以在UNIX,Linux和Windows操作系统中看到这种结构的证据。

分层方法

单体方法通常称为紧密耦合系统,因为对系统某一部分的更改可能对其他部分产生广泛的影响。或者,我们可以设计一个松耦合系统。这样的系统分为具有特定功能和有限功能的单独的较小组件。所有这些组件共同构成了内核。这种模块化方法的优点是,一个组件中的更改只会影响该组件,而不会影响其他组件,从而使系统实现者在创建和更改系统内部工作方面具有更大的自由度。

可以通过多种方式使系统模块化。一种方法是分层方法,其中将操作系统分为多个层(级别)。底层(第0层)是硬件;最高的(第N层)是用户界面。这种分层结构如下图所示。

b387f42ce95874b004bf425792f32e3e.png

操作系统层是由数据和可以操纵这些数据的操作组成的抽象对象的实现。典型的操作系统层(例如,M层)由数据结构和一组可以由更高层调用的功能组成。 M层又可以调用较低层的操作。

分层方法的主要优点是构造和调试简单。选择这些层,以便每个层仅使用较低层的功能(操作)和服务。这种方法简化了调试和系统验证。可以对第一层进行调试,而无需担心系统的其余部分,因为根据定义,它仅使用基本硬件(假定正确)来实现其功能。一旦调试完了第一层,当调试第二层时,就可以假定其正确运行,以此类推。如果在调试特定层期间发现错误,则该错误必定在该层上,因为它下面的层已被调试。因此,简化了系统的设计和实现。

每一层仅通过较低层提供的操作来实现。单一层不需要知道这些操作是如何实现的。它只需要知道这些操作的作用即可。因此,每一层都对较高层隐藏某些数据结构,操作和硬件的存在。

分层系统已成功用于计算机网络(例如TCP / IP)和Web应用程序中。但是,操作系统使用纯分层方法则相对较少。一个原因是适当定义每一层功能的有些挑战。另外,由于用户程序遍历多层以获得操作系统服务需要开销,因此此类系统的整体性能很差。但是,某些分层在现代操作系统中很常见。通常,这些系统有较少但具有更多功能的层,从而提供了模块化代码的大多数优点,同时避免了层定义和交互的问题。

微内核

我们已经看到原始的UNIX系统具有单体结构。随着UNIX的扩展,内核变得庞大且难以管理。在1980年代中期,卡内基梅隆大学的研究人员开发了一种名为Mach的操作系统,该操作系统使用微内核方法对内核进行了模块化。此方法通过从内核中删除所有不必要的组件并将其实现为驻留在单独地址空间中的用户级程序来构造操作系统。结果得到了是较小的内核。关于哪些服务应该保留在内核中以及哪些应该在用户空间中实现,几乎没有共识。但是,通常,微内核除了提供通信功能外,还提供最少的进程和内存管理。下图说明了典型的微内核的体系结构。

b0474c94f6acc2cd6c76b3d9e3910ba0.png

微内核的主要功能是提供客户端程序与也在用户空间中运行的各种服务之间的通信。通过消息传递来提供通信。例如,如果客户端程序希望访问文件,则它必须与文件服务器进行交互。客户端程序和服务永远不会直接交互。相反,它们通过交换消息间接进行通信与微内核。

微内核方法的一个好处是,它使扩展操作系统变得更加容易。所有新服务都添加到用户空间,因此不需要修改内核。当必须修改内核时,由于微内核是较小的内核,因此更改趋向于减少。最终产生的操作系统变得更容易从一种硬件设计移植到另一种硬件设计。由于大多数服务是作为用户(而不是内核)进程运行的,因此微内核还提供了更高的安全性和可靠性。如果服务失败,则其余操作系统将保持不变。

微内核操作系统的最著名的例子也许是Darwin,它是macOS和iOS操作系统的内核组件。实际上,达尔文由两个内核组成,其中之一是Mach微内核。另一个例子是QNX,这是一种用于嵌入式系统的实时操作系统。 QNX Neutrino微内核为消息传递和流程调度提供服务。它还处理底层网络通信和硬件中断。 QNX中的所有其他服务由,在用户模式下且在内核外部,运行的标准进程提供。

不幸的是,由于增加的系统功能开销,微内核的性能可能会受到影响。当两个用户级服务必须通信时,必须在服务之间复制消息,这些服务位于单独的地址空间中。另外,操作系统可能必须从一个进程切换到下一个进程以交换消息。复制消息和在进程之间切换所涉及的开销一直是基于微内核的操作系统增长的最大障碍。考虑Windows NT的历史:第一个发行版具有分层的微内核组织。与Windows95相比,此版本的性能较低。 Windows NT 4.0通过将层从用户空间移动到内核空间并将它们更紧密地集成在一起,部分地纠正了性能问题。在设计Windows XP时,Windows体系结构已经比微内核变得更加单一。

模块化

当前最佳的操作系统设计方法论可能涉及使用可加载内核模块(loadable kernel modules,LKMs)。在这里,内核具有一组核心组件,并且可以在启动时或运行时通过模块链接其他服务。这种类型的设计在UNIX的现代实现中很常见,例如Linux,mac OS和Solaris,以及Windows。

该设计思想是让内核提供核心服务,同时在内核运行时动态地实现其他服务。动态链接服务比直接向内核添加新功能要好,后者需要在每次更改时重新编译内核。因此,例如,我们可以将CPU调度和内存管理算法直接构建到内核中,然后通过可加载模块添加对不同文件系统的支持。

总体结果类似于分层系统,其中每个内核部分都有定义的受保护的接口。但是它比分层系统更灵活,因为任何模块都可以调用任何其他模块。该方法也与微内核方法相似,因为主要模块仅具有核心功能,并且具有如何加载和与其他模块通信的知识。但它效率更高,因为模块无需调用消息传递即可进行通信。

Linux使用可加载的内核模块,主要用于支持设备驱动程序和文件系统。 LKM可以在系统启动(或引导)时或在运行时(例如,将USB设备插入正在运行的计算机中)“插入”到内核中。如果Linux内核没有必需的驱动程序,则可以动态加载它。 LKM也可以在运行时从内核中删除。对于Linux,LKM允许其使用动态模块化内核,同时保持单体系统的性能优势。


混合系统

实际上,很少有操作系统采用单个严格定义的结构。相反,它们结合了不同的结构,从而形成了解决性能,安全性和可用性问题的混合系统。例如,Linux是单体的,因为将操作系统放在单个地址空间中提供非常高效的性能。但是,它也是模块化的,因此可以将新功能动态添加到内核中。 Windows在很大程度上也是单体的(同样也是出于性能方面的考虑),但是它保留了微内核系统的某些典型行为,包括为以用户模式进程运行的单独子系统(称为操作系统的personalities)提供支持。 Windows系统还提供对可动态加载的内核模块的支持。

macOS和iOS

Apple的macOS操作系统主要在台式机和笔记本电脑系统上运行,而iOS是为iPhone智能手机和iPad平板电脑设计的移动操作系统。在体系结构上,macOS和iOS有很多共同点,因此我们将它们一起展示,重点介绍它们的共通之处以及彼此之间的区别。这两个系统的总体架构如下图所示。

718ae1f9a9b91a9e8cb1a8446303c5fd.png

各层的重点包括以下内容:

  • User experience layer用户体验层。该层定义了允许用户与计算设备进行交互的软件接口。 macOS使用专为鼠标或触控板设计的Aqua用户界面,而iOS使用Springboard用户界面,专为触摸设备而设计。
  • Application frame layer应用框架层。该层包括Cocoa和Cocoa Touch框架,它们提供了Objective-C和Swift编程语言的API。 Cocoa和Cocoa Touch之间的主要区别在于,前者用于开发macOS应用程序,而后者则由iOS用于提供对以下特性的支持:移动设备,例如触摸屏。
  • Core frameworks核心框架。该层定义了支持图形和媒体的框架,包括Quicktime和Open GL
  • Kernel environment内核环境。此环境也称为Darwin,包括Mach微内核和BSD UNIX内核。

如上图所示,可以将应用程序设计为利用用户体验功能的或绕过它们,并直接与应用程序框架或核心框架进行交互。此外,应用程序可以完全放弃框架并直接与内核进行通信环境。 (后一种情况的一个示例是通过使用POSIX系统调用,编写的无用户界面的C程序。)

macOS和iOS之间的一些重要区别包括:

  • 由于mac OS专用于台式机和笔记本电脑系统,因此将其编译为可在Intel体系结构上运行。 iOS是为移动设备设计的,因此已针对基于ARM的体系结构进行了编译。同样,对iOS内核进行了一些修改,以解决移动系统的特定功能和需求,例如电源管理和主动内存管理。此外,iOS的安全设置比macOS更为严格。
  • 与Mac OS相比,iOS操作系统通常对开发人员的限制更大,甚至可能对开发人员不开放。例如,iOS在iOS上限制对POSIX和BSD API的访问,而macOS上的开发人员可以使用它们。

现在,我们重点介绍使用混合结构的达尔文。达尔文是一个分层系统,主要由Mach微内核和BSD UNIX内核组成。达尔文的结构如下图所示。

9e126977b7272424626d3655b276d9fb.png

大多数操作系统(例如,通过UNIX和Linux系统上的标准C库)为内核提供单个系统调用接口,而Darwin提供了两个系统调用接口:Mach系统调用(称为trap)和BSD系统调用(提供POSIX功能)。这些系统调用的接口是一组丰富的库,这些库不仅包括标准C库,还包括提供网络,安全性和编程语言支持的库(仅举几例)。

在系统调用界面下,Mach提供了基本的操作系统服务,包括内存管理,CPU调度和进程间通信(IPC)功能,例如消息传递和远程过程调用(RPC)。 Mach提供的许多功能都可以通过内核抽象kernel abstraction获得,其中包括任务(Mach进程),线程,内存对象和端口(用于IPC)。例如,应用程序可以使用BSD POSIX fork()系统调用来创建新进程。反过来,Mach将使用任务内核抽象来表示内核中的进程。

除了Mach和BSD之外,内核环境还提供了一个I / O kit,用于开发设备驱动程序和可动态加载的模块(mac OS称为内核扩展或kexts)。

在上文微内核节中,我们描述了在用户空间中运行的不同服务之间传递消息的开销如何影响微内核的性能。为了解决此类性能问题,Darwin将Mach,BSD,I / O套件和所有内核扩展组合到一个地址空间中。因此,就各种子系统在用户空间中运行的意义而言,Mach并不是纯粹的微内核。在Mach内仍会发生消息传递,但由于服务可以访问相同的地址空间,因此无需复制。

苹果已经发布了达尔文操作系统作为开源。这也导致了各种项目为达尔文增加了额外的功能,例如X-11窗口系统以及对其他文件系统的支持。但是,与达尔文不同的是,Cocoa接口以及其他专属Apple可用于开发Mac OS应用程序的框架是封闭的。

Android

Android操作系统由开放手机联盟(主要由Google领导)设计,并且是针对Android智能手机和平板电脑开发的。 iOS被设计为可在Apple移动设备上运行并且是非开源的,而Android可在各种移动平台上运行并且是开源的,部分解释了其迅速普及的原因。 Android的结构如下图所示。

960ad324c155fd7f13ff5c140b574bd1.png

Android与iOS类似,它是分层的软件堆栈,提供了一组丰富的框架,支持图形,音频和硬件功能。这些功能又为开发可在支持Android的设备上运行的移动应用程序提供了平台。

Android设备的软件设计人员使用Java语言开发应用程序,但是他们通常不使用标准Java API。 Google为Java开发设计了一个单独的Android API。 Java应用程序被编译为可以在Android RunTime ART上执行的形式,后者是为Android设计的虚拟机,并针对内存和CPU处理能力有限的移动设备进行了优化。 Java程序首先被编译为Java字节码.class文件,然后转换为可执行的.dex文件。许多Java虚拟机执行即时(JIT)编译以为了提高应用程序效率,ART执行了ahead-of-time(AOT)编译。在此,当.dex文件安装在设备上时,它们将被编译成本机代码,它们可以在ART上执行。 AOT编译可提高应用程序执行效率,并降低功耗,这对于移动系统至关重要。

Android开发人员还可以编写使用Java本机接口(或JNI)的Java程序,该程序允许开发人员绕过虚拟机,而是编写可以访问特定硬件功能的Java程序。使用JNI编写的程序通常无法从一个硬件设备移植到另一个硬件设备

可用于Android应用程序的一组本机库包括用于开发Web浏览器(webkit),数据库支持(SQLite)和网络支持的框架,例如安全套接字(SSL)。

由于Android可以在几乎无限数量的硬件设备上运行,因此Google选择通过硬件抽象层(HAL)对物理硬件进行抽象。通过抽象化所有硬件,例如摄像机,GPS芯片和其他传感器,HAL为应用程序提供了与特定硬件无关的一致视图。当然,此功能使开发人员可以编写在不同硬件平台上移植的程序。

Linux系统使用的标准C库是GNU C库(glibc)。 Google为Android开发了Bionic标准C库。 Bionic不仅比glibc拥有更小的内存占用,而且还专为移动设备上较慢的CPU设计。 (此外,Bionic允许Google绕过glibc的GPL许可。)

Linux内核位于Android软件堆栈的底部。 Google已在多个领域修改了Android中使用的Linux内核,以支持移动系统的特殊需求,例如电源管理。它还更改了内存管理和分配,并添加了一种称为Binder的新IPC形式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值