提示:冠盖满京华,斯人独憔悴
文章目录
- 声明
- 1.3.1 操作系统的运行机制
- 1.3.2 中断和异常
- 1.3.3 系统调用
- 1.4.1 操作系统体系结构
- 1.4.2 操作系统体系
- 1.5 操作系统引导
- 1.6 虚拟机
声明
本文章内容是根据王道教材以及王道的视频课所写,写的目的方便我自己进行学习,也希望大家一起进步学习,若是文章内容有侵权请联系删帖
1.3.1 操作系统的运行机制
应用程序:比如QQ什么的
内核程序:包含操作系统中最重要,最内核的,最必不可少的东西,所以操作系统所有的功能未必在内核中,如用户图像化界面GUI
在计算机系统中,通常CPU执行两种不同性质的程序:一种是操作系统内核程序;另一种是用户自编程序(即系统外层的应用程序,或简称“应用程序”)。对操作系统而言,这两种程序的作用不同,前者是后者的管理者,因此“管理程序”(即内核程序)要执行一些特权指令,而“被管理程序”(即用户自编程序)出于安全考虑不能执行这些指令。
1)特权指令,是指不允许用户直接使用的指令,如IO指令、置中断指令,存取用于内存保护的寄存器、送程序状态字到程序状态字寄存器等的指令。
2)非特权指令,是指允许用户直接使用的指令,它不能直接访问系统中的软硬件资源,仅限于访问用户的地址空间,这也是为了防止用户程序对系统造成破坏。
在具体实现上,将CPU的运行模式划分为用户态(目态)和核心态(又称管态、内核态)。可以理解为CPU内部有一个小开关,当小开关为0时,CPU处于核心态,此时CPU可以执行特权指令,切换到用户态的指令也是特权指令。当小开关为1时,CPU处于用户态,此时CPU 只能执行非特权指令。应用程序运行在用户态,操作系统内核程序运行在核心态。应用程序向操作系统请求服务时通过使用访管指令,从而产生一个中断事件将操作系统转换为核心态。
在软件工程思想和结构化程序设计方法影响下诞生的现代操作系统,几乎都是分层式的结构。操作系统的各项功能分别被设置在不同的层次上。一些与硬件关联较紧密的模块,如时钟管理、中断处理、设备驱动等处于最低层。其次是运行频率较高的程序,如进程管理、存储器管理和设备管理等。这两部分内容构成了操作系统的内核。这部分内容的指令操作工作在核心态。
内核是计算机上配置的底层软件,它管理着系统的各种资源,可以看作是连接应用程序和硬件的一座桥梁,大多数操作系统的内核包括4方面的内容。
1.时钟管理
在计算机的各种部件中,时钟是最关键的设备。时钟的第一功能是计时,操作系统需要通过时钟管理,向用户提供标准的系统时间。另外,通过时钟中断的管理,可以实现进程的切换。例如,在分时操作系统中采用时间片轮转调度,在实时系统中按截止时间控制运行,在批处理系统中通过时钟管理来衡量一个作业的运行程度等。因此,系统管理的方方面面无不依赖于时钟。
2.中断机制
引入中断技术的初衷是提高多道程序运行环境中CPU的利用率,而且主要是针对外部设备的。后来逐步得到发展,形成了多种类型,成为操作系统各项操作的基础。例如,键盘或鼠标信息的输入、进程的管理和调度、系统功能的调用、设备驱动、文件访问等,无不依赖于中断机制。可以说,现代操作系统是靠中断驱动的软件。
中断机制中,只有一小部分功能属于内核,它们负责保护和恢复中断现场的信息,转移控制权到相关的处理程序。这样可以减少中断的处理时间,提高系统的并行处理能力。
3.原语
按层次结构设计的操作系统,底层必然是一些可被调用的公用小程序,它们各自完成一个规定的操作。它们的特点如下:
1)处于操作系统的最底层,是最接近硬件的部分。
2)这些程序的运行具有原子性,其操作只能一气呵成(出于系统安全性和便于管理考虑)。3)这些程序的运行时间都较短,而且调用频繁。
通常把具有这些特点的程序称为原语(Atomic Operation)。定义原语的直接方法是关闭中断,让其所有动作不可分割地完成后再打开中断。系统中的设备驱动、CPU 切换、进程通信等功能中的部分操作都可定义为原语,使它们成为内核的组成部分。
4.系统控制的数据结构及处理
系统中用来登记状态信息的数据结构很多,如作业控制块、进程控制块(PCB)、设备控制块、各类链表、消息队列、缓冲区、空闲区登记表、内存分配表等。为了实现有效的管理,系统需要一些基本的操作,常见的操作有以下3种:
1)进程管理。进程状态管理、进程调度和分派、创建与撤销进程控制块等。
2)存储器管理。存储器的空间分配和回收、内存信息保护程序、代码对换程序等。
3)设备管理。缓冲区管理、设备分配和回收等。
从上述内容可以了解,核心态指令实际上包括系统调用类指令和一些针对时钟、中断和原语的操作指令。
但是CPU任何进行两种状态之间的切换?
本节总结
1.3.2 中断和异常
中断的作用
中断(Interruption)也称外中断,是指来自CPU执行指令外部的事件,通常用于信息输入/输出,如设备发出的I/O结束中断,表示设备输入/输出处理已经完成。时钟中断,表示一个固定的时间片已到,让处理机处理计时、启动定时运行的任务等。
异常(Exception)也称内中断,是指来自CPU执行指令内部的事件,如程序的非法操作码、地址越界、运算溢出、虚存系统的缺页及专门的陷入指令等引起的事件。异常不能被屏蔽,一旦出现,就应立即处理。
在操作系统中引入核心态和用户态这两种工作状态后,就需要考虑这两种状态之间如何切换。操作系统内核工作在核心态,而用户程序工作在用户态。系统不允许用户程序实现核心态的功能,而它们又必须使用这些功能。因此,需要在核心态建立一些“门”,以便实现从用户态进入核心态。在实际操作系统中,CPU运行上层程序时唯一能进入这些“门”的途径就是通过中断或异常。发生中断或异常时,运行用户态的CPU会立即进入核心态,这是通过硬件实现的(例如,用一个特殊寄存器的一位来表示CPU所处的工作状态,0表示核心态,1表示用户态。若要进入核心态,则只需将该位置О即可)。中断是操作系统中非常重要的一个概念,对一个运行在计算机上的实用操作系统而言,缺少了中断机制,将是不可想象的。原因是,操作系统的发展过程大体上就是一个想方设法不断提高资源利用率的过程,而提高资源利用率就需要在程序并未使用某种资源时,把它对那种资源的占有权释放,而这一行为就需要通过中断实现。
中断的类型
外中断可分为可屏蔽中断和不可屏蔽中断。可屏蔽中断是指通过INTR线发出的中断请求,通过改变屏蔽字可以实现多重中断,从而使得中断处理更加灵活。不可屏蔽中断是指通过NMI线发出的中断请求,通常是紧急的硬件故障,如电源掉电等。此外,异常也是不能被屏蔽的。
异常可分为故障、自陷和终止。故障(Fault)通常是由指令执行引起的异常,如非法操作码、缺页故障、除数为0、运算溢出等。自陷〈Trap)是一种事先安排的“异常”事件,用于在用户态下调用操作系统内核程序,如条件陷阱指令。终止(Abort)是指出现了使得CPU无法继续执行的硬件故障,如控制器出错、存储器校验错等。故障异常和自陷异常属于软件中断(程序性异常),终止异常和外部中断属于硬件中断。
中断机制的基本原理
中断和异常处理过程的大致描述如下:当CPU在执行用户程序的第i条指令时检测到一个异常事件,或在执行第i条指令后发现一个中断请求信号,则 CPU打断当前的用户程序,然后转到相应的中断或异常处理程序去执行。若中断或异常处理程序能够解决相应的问题,则在中断或异常处理程序的最后,CPU通过执行中断或异常返回指令,回到被打断的用户程序的第i条指令或第i+1条指令继续执行;若中断或异常处理程序发现是不可恢复的致命错误,则终止用户程序。通常情况下,对中断和异常的具体处理过程由操作系统(和驱动程序)完成。
知识回顾
1.3.3 系统调用
所谓系统调用,是指用户在程序中调用操作系统所提供的一些子功能,系统调用可视为特殊的公共子程序。系统中的各种共享资源都由操作系统统一掌管,因此在用户程序中,凡是与资源有关的操作(如存储分配、进行IO传输及管理文件等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。通常,一个操作系统提供的系统调用命令有几十条乃至上百条之多。这些系统调用按功能大致可分为如下几类。
设备管理。完成设备的请求或释放,以及设备启动等功能。·文件管理。完成文件的读、写、创建及删除等功能。
进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。进程通信。完成进程之间的消息传递或信号传递等功能。
内存管理。完成内存的分配、回收以及获取作业占用内存区大小及始址等功能。
显然,系统调用相关功能涉及系统资源管理、进程管理之类的操作,对整个系统的影响非常
大,因此必定需要使用某些特权指令才能完成,所以系统调用的处理需要由操作系统内核程序负责完成,要运行在核心态。用户程序可以执行陷入指令(又称访管指令或trap指令)来发起系统调用,请求操作系统提供服务。可以这么理解,用户程序执行“陷入指令”,相当于把 CPU的使用权主动交给操作系统内核程序(CPU 状态会从用户态进入核心态),之后操作系统内核程序再对系统调用请求做出相应处理。处理完成后,操作系统内核程序又会把CPU的使用权还给用户程序(即CPU状态会从核心态回到用户态)。这么设计的目的是:用户程序不能直接执行对系统影响非常大的操作,必须通过系统调用的方式请求操作系统代为执行,以便保证系统的稳定性和安全性,防止用户程序随意更改或访问重要的系统资源,影响其他进程的运行。
这样,操作系统的运行环境就可以理解为:用户通过操作系统运行上层程序(如系统提供的命令解释程序或用户自编程序),而这个上层程序的运行依赖于操作系统的底层管理程序提供服务支持,当需要管理程序服务时,系统则通过硬件中断机制进入核心态,运行管理程序:也可能是程序运行出现异常情况,被动地需要管理程序的服务,这时就通过异常处理来进入核心态。管理程序运行结束时,用户程序需要继续运行,此时通过相应的保存的程序现场退出中断处理程序或异常处理程序,返回断点处继续执行
在操作系统这一层面上,我们关心的是系统核心态和用户态的软件实现与切换,对于硬件层面的具体理解,可以结合“计算机组成原理”课程中有关中断的内容进行学习
下面是一些由用户态传向核心态的例子
1)用户程序要求操作系统的服务,即系统调用
2)发生一次中断
3)用户程序中产生了一个错误状态
4)用户程序中企图执行一条特权指令
5)从核心态转向用户态由一条指令实现,这条指令也是特权命令,一般是中断返回指令
注意:由用户态进入核心态,不仅状态需要切换,而且所用的堆栈也可能需要由用户堆栈切换为系统堆栈,但这个系统堆栈也是属于该进程的。
若程序的运行由用户态转到核心态,则会用到访管指令,访管指令是在用户态使用的,所以它不可能是特权指令。
为什么说系统调用是必须的
什么功能要用到系统调用
简单来说就是对共享资源的有关的操作就需要系统调用
系统调用的过程
如果一个应用程序执行了陷入指令,也就意味着应用程序主动的把CPU的控制权主动的还给了系统,用这种方式来请求操作系统的服务
知识回顾
1.4.1 操作系统体系结构
实现程序并发就一定离不开时钟管理
这些内核程序必须运行在内核态,与硬件关联较紧密的模块一定是放在内核态,若是不会涉及硬件的管理工作,有些操作系统则会将这些管理功能不放在内核中,而仅仅保留与硬件接触最紧密的部分,因此这就引出了两种截然不同的内核设计方法,所有的功能都包含在操作系统内核中的,这种叫做大内核,只保留与硬件功能最紧密的叫做微内核,若是使用微内核这种结构,则微内核的管理功能是运行在内核态,而类如进程管理等功能则是运行在用户态,
这会对系统的性能造成一定的影响,如下图若是使用大内核这种结构,当要进行进程管理等一系列操作的时候,CPU从用户态变为内核态开始运行这一系列的内核程序,若是使用微内核的,应用程序向操作系统提出服务的请求,而进程管理这个模块处理的时候也是需要得到内核的支持,所以每一个模块都需要从用户态转到内核态,服务完成之后又会从内核态转用户态
知识回顾
从操作系统的内核架构来划分,可分为宏内核和微内核。
宏内核,也称单内核或大内核,是指将系统的主要功能模块都作为一个紧密联系的整体运行在核心态,从而为用户程序提供高性能的系统服务。因为各管理模块之间共享信息,能有效利用相互之间的有效特性,所以具有无可比拟的性能优势。
随着体系结构和应用需求的不断发展,需要操作系统提供的服务越来越复杂,操作系统的设计规模急剧增长,操作系统也面临着“软件危机”困境。就像一个人,越胖活动起来就越困难。所以就出现了微内核技术,就是将一些非核心的功能移到用户空间,这种设计带来的好处是方便扩展系统,所有新服务都可以在用户空间增加,内核基本不用去做改动。
从操作系统的发展来看,宏内核获得了绝对的胜利,目前主流的操作系统,如Windows.Android、iOS、macOS、Linux等,都是基于宏内核的构架。但也应注意到,微内核和宏内核一直是同步发展的,目前主流的操作系统早已不是当年纯粹的宏内核构架了,而是广泛吸取微内核构架的优点而后揉合而成的混合内核。当今宏内核构架遇到了越来越多的困难和挑战,而微内核的优势似乎越来越明显,尤其是谷歌的Fuchsia和华为的鸿蒙OS,都瞄准了微内核构架。
微内核
微内核构架,是指将内核中最基本的功能保留在内核,而将那些不需要在核心态执行的功能移到用户态执行,从而降低内核的设计复杂性。那些移出内核的操作系统代码根据分层的原则被划分成若干服务程序,它们的执行相互独立,交互则都借助于微内核进行通信。
微内核结构将操作系统划分为两大部分:微内核和多个服务器。微内核是指精心设计的、能实现操作系统最基本核心功能的小型内核,通常包含:①与硬件处理紧密相关的部分:②一些较基本的功能:③客户和服务器之间的通信。这些部分只是为构建通用操作系统提供一个重要基础,这样就可以确保将内核做得很小。操作系统中的绝大部分功能都放在微内核外的一组服务器(进程)中实现,如用于提供对进程(线程〉进行管理的进程(线程)服务器、提供虚拟存储器管理功能的虚拟存储器服务器等,它们都是作为进程来实现的,运行在用户态,客户与服务器之间是借助微内核提供的消息传递机制来实现交互的。
在微内核结构中,为了实现高可靠性,只有微内核运行在内核态,其余模块都运行在用户态,一个模块中的错误只会使这个模块崩溃,而不会使整个系统崩溃。例如,文件服务代码运行时出了问题,宏内核因为文件服务是运行在内核态的,系统直接就崩溃了。而微内核的文件服务是运行在用户态的,只要把文件服务功能强行停止,然后重启,就可以继续使用,系统不会崩溃。
(2)微内核的基本功能
微内核结构通常利用“机制与策略分离”的原理来构造OS结构,将机制部分以及与硬件紧密相关的部分放入微内核。微内核通常具有如下功能:
①进程(线程)管理。进程(线程)之间的通信功能是微内核OS最基本的功能,此外还有进程的切换、进程的调度,以及多处理机之间的同步等功能,都应放入微内核中。举个例子,为实现进程调度功能,需要在进程管理中设置一个或多个进程优先级队列,这部分属于调度功能的机制部分,应将它放入微内核中。而对用户进程如何分类,以及优先级的确认方式,则属于策略问题,可将它们放入微内核外的进程管理服务器中。
②低级存储器管理。在微内核中,只配置最基本的低级存储器管理机制,如用于实现将逻辑地址变换为物理地址等的页表机制和地址变换机制,这一部分是依赖于硬件的,因此放入微内核。而实现虚拟存储器管理的策略,则包含应采取何种页面置换算法,采用何种内存分配与回收的策略,应将这部分放在微内核外的存储器管理服务器中。
③中断和陷入处理。微内核OS将与硬件紧密相关的一小部分放入微内核,此时微内核的主要功能是捕获所发生的中断和陷入事件,并进行中断响应处理,在识别中断或陷入的事件后,再发送给相关的服务器来处理,故中断和陷入处理也应放入微内核。
微内核操作系统将进程管理、存储器管理以及IO管理这些功能一分为二,属于机制的很小一部分放入微内核,而绝大部分放入微内核外的各种服务器实现,大多数服务器都要比微内核大。因此,在采用客户/服务器模式时,能把微内核做得很小
(3)微内核的特点
微内核结构的主要优点如下所示。
①扩展性和灵活性。许多功能从内核中分离出来,当要修改某些功能或增加新功能时,只需在相应的服务器中修改或新增功能,或再增加一个专用的服务器,而无须改动内核代码。
②可靠性和安全性。前面已举例说明。
③可移植性。与CPU和IO硬件有关的代码均放在内核中,而其他各种服务器均与硬件平台无关,因而将操作系统移植到另一个平台上所需做的修改是比较小的。
④分布式计算。客户和服务器之间、服务器和服务器之间的通信采用消息传递机制,这就使得微内核系统能很好地支持分布式系统和网络系统。
微内核结构的主要问题是性能问题,因为需要频繁地在核心态和用户态之间进行切换,操作系统的执行开销偏大。为了改善运行效率,可以将那些频繁使用的系统服务移回内核,从而保证系统性能,但这又会使微内核的容量明显地增大。
虽然宏内核在桌面操作系统中取得了绝对的胜利,但是微内核在实时、工业、航空及军事应用中特别流行,这些领域都是关键任务,需要有高度的可靠性。
1.4.2 操作系统体系
分层结构的操作系统
每一层只能调用相邻更低一层提供的接口,若是我们在原有的两层之间新加一层,我们只需要保证向上层提供的接口,以及对下层的使用,因此加层是比较容易的
分层法是将操作系统分为若干层,最底层(层0)为硬件,最高层(层N)为用户接口,每
层只能调用紧邻它的低层的功能和服务(单向依赖)。
分层法的优点:①便于系统的调试和验证,简化了系统的设计和实现。第1层可先调试而无须考虑系统的其他部分,因为它只使用了基本硬件。第1层调试完且验证正确之后,就可以调试第2层,如此向上。如果在调试某层时发现错误,那么错误应在这一层上,这是因为它的低层都调试好了。②易扩充和易维护。在系统中增加、修改或替换一层中的模块或整层时,只要不改变相应层间的接口,就不会影响其他层。
分层法的问题:①合理定义各层比较困难。因为依赖关系固定后,往往就显得不够灵活。②效率较差。操作系统每执行一个功能,通常要自上而下地穿越多层,各层之间都有相应的层间通信机制,这无疑增加了额外的开销,导致系统效率降低。
模块化的操作系统
因为模块间相互依赖,所以若是其中出了问题,则难以发现问题出现在哪
在划分模块时,如果将模块划分得太小,虽然能降低模块本身的复杂性,但会使得模块之间的联系过多,造成系统比较混乱:如果模块划分得过大,又会增加模块内部的复杂性,显然应在两者间进行权衡。此外,在划分模块时,要充分考虑模块的独立性问题,因为模块独立性越高,各模块间的交互就越少,系统的结构也就越清晰。衡量模块的独立性主要有两个标准;
内聚性,模块内部各部分间联系的紧密程度。内聚性越高,模块独立性越好。·
耦合度,模块间相互联系和相互影响的程度。耦合度越低,模块独立性越好。
模块化的优点:①提高了操作系统设计的正确性、可理解性和可维护性;②增强了操作系统的可适应性:③加速了操作系统的开发过程。
模块化的缺点:①模块间的接口规定很难满足对接口的实际需求。②各模块设计者齐头并进,每个决定无法建立在上一个已验证的正确决定的基础上,因此无法找到一个可靠的决定顺序。
1.5 操作系统引导
操作系统引导——开机的时候,怎么让操作系统运行起来?
按照操作系统之后
操作系统(如 Windows、Linux等)是一种程序,程序以数据的形式存放在硬盘中,而硬盘通常分为多个区,一台计算机中又有多个或多种外部存储设备。操作系统引导是指计算机利用CPU运行特定程序,通过程序识别硬盘,识别硬盘分区,识别硬盘分区上的操作系统,最后通过程序启动操作系统,一环扣一环地完成上述过程。
常见操作系统的引导过程如下:
①激活CPU。激活的CPU读取ROM中的 boot程序,将指令寄存器置为BIOS(基本输入/输出系统)的第一条指令,即开始执行 BIOS的指令。
②硬件自检。启动BIOS程序后,先进行硬件自检,检查硬件是否出现故障。如有故障,主板会发出不同含义的蜂鸣,启动中止;如无故障,屏幕会显示CPU、内存、硬盘等信息。
③加载带有操作系统的硬盘。硬件自检后,BIOS开始读取 Boot Sequence(通过CMOS里保存的启动顺序,或者通过与用户交互的方式),把控制权交给启动顺序排在第一位的存储设备,然后 CPU将该存储设备引导扇区的内容加载到内存中。
④加载主引导记录MBR。硬盘以特定的标识符区分引导硬盘和非引导硬盘。如果发现一个存储设备不是可引导盘,就检查下一个存储设备。如无其他启动设备,就会死机。主引导记录MBR的作用是告诉CPU 去硬盘的哪个主分区去找操作系统。
⑤扫描硬盘分区表,并加载硬盘活动分区。MBR包含硬盘分区表,硬盘分区表以特定的标识符区分活动分区和非活动分区。主引导记录扫描硬盘分区表,进而识别含有操作系统的硬盘分区(活动分区)。找到硬盘活动分区后,开始加载硬盘活动分区,将控制权交给活动分区。
6 加载分区引导记录PBR。读取活动分区的第一个扇区,这个扇区称为分区引导记录(PBR),其作用是寻找并激活分区根目录下用于引导操作系统的程序(启动管理器)。
⑦加载启动管理器。分区引导记录搜索活动分区中的启动管理器,加载启动管理器。
⑧加载操作系统。
1.6 虚拟机
两个进程同时在一个操作系统之上可能会有安全隐患,也会相互争抢操作系统的这个管理资源,一种方法就是将其中一个进程放在另外一个物理机器上,但是这又会导致物理机器的极大浪费,因此有人发明了虚拟机
第一类会将物理机器虚拟化为多台虚拟机器,会将整个应用资源划分为多个部分,给每一台虚拟机使用,每一个虚拟机上可以按照各自的操作系统,CPU时间片进行划分,磁盘内存进行区域划分,只有虚拟机管理程序是运行在内核态,只有它可以使用特权最高的那些指令,而上层的操作系统和 应用程序是运行在用户态,但是上层的操作系统并不知道,所以依然会使用一些特权指令,但是只有虚拟机管理程序是在内核态,不能让操作系统使用这些特权指令,若是上层要使用特权指令,则会被虚拟机管理程序截获,会将这些特权指令进行一些等价的转化,给上层一种执行成功的感觉
第二类不是直接运行在硬件上,而是运行在宿主操作系统上,如VMware,这个虚拟机管理程序想要给虚拟机分配硬件资源,只能先请求宿主操作系统给他进行分配,然后虚拟机管理程序进行再分配