侧边栏壁纸
博主头像
LittleAO的学习小站 博主等级

在知识的沙漠寻找绿洲

  • 累计撰写 125 篇文章
  • 累计创建 27 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

操作系统之 操作系统基础

LittleAO
2024-07-26 / 0 评论 / 0 点赞 / 38 阅读 / 0 字
温馨提示:
本文最后更新于2024-08-02,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

操作系统的概念和功能

现在每个人都和操作系统密切相关。工作中我们会用到Windows、MacOS这些操作系统处理工作内容。手机上我们会使用Android、iOS来刷剧听歌。企业可能会使用Linux操作系统为用户提供服务。那么这个操作系统究竟是什么?

概念

科学的定义是:操作系统是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的环境和接口,是计算机系统中最基本的系统软件

看起来有些抽象?不用担心,操作系统这个系列全都是围绕上面这句话而展开的。

操作系统就像是一个粘合剂,连接了硬件与应用程序。应用程序需要依托于操作系统才能运行,硬件也听从操作系统的调度来适时运行。

功能

操作系统是系统资源的管理者

操作系统可以对处理机、存储器、文件和设备进行有效的管理,保证安全性和高效性。

例如,你可以打开设备管理器,看看操作系统负责管理的设备有哪些:

操作系统可以处理鼠标的输入,进行一定的处理,变成光标出现在我们的显示器上。

操作系统可以将一个软件移入内存之中,然后组织处理器对处理移入内存的应用程序。

向上层提供方便易用的服务

硬件只能听懂二进制的指令,不便于用户和应用程序(上层)进行操作。操作系统就封装一些指令,让他们变成通俗易懂的指令,使用户能够更加方便的使用服务。

随着硬件性能的提升,更加多样化且易于使用的功能也出现在操作系统之中。例如GUI(图形化用户接口),用户能够使用简单的图形界面完成一些指令,降低了使用门槛。例如Linux的GNome。

早期操作系统是一个黑色的窗口,用户在这个黑色窗口输入一些指令,操作系统相应的完成这些指令。这种服务方式称为联机命令接口(交互式命令接口),你可以右击Windows开始键,打开PowerShell(终端),PowerShell就是联机命令接口。

有联机命令接口就有脱机命令接口,脱机命令接口又称批处理接口,是一个文件,里面包含了一系列的指令。例如Windows系统下的.bat文件就是脱机命令接口。

此外还有专门提供给程序员使用的程序接口。程序员编写的程序会调用程序接口来完成一系列的指令。

作为最接近硬件的层次

使用计算机,我们买来了所有的硬件,把它们拼装到一起。这时候并不能使用,我们需要一个东西来整合这些硬件,这个东西就是操作系统。整合这些硬件,让它们各司其职,完成一种功能的扩展。

操作系统的功能

并发

操作系统具有并发性,也就是说操作系统可以同时运行多个应用程序。并发的的意思是在宏观上看起来两件事物同时在运行,实际上在更小的观察尺度上,事物是轮流运行的。由于替换的速度很快,看起来像是在同时运行。

真正的同时运行的概念叫做并行

对于单核CPU来讲,同一时刻只能运行一个程序,由于操作系统的并发性,单核CPU也能“同时”运行多个程序。

对于多核CPU来讲,同一时刻可以运行多个程序。具有并行性。

共享

操作系统具有共享性。共享指的是资源共享,指系统中的资源可供内存中多个并发执行的进程共同使用。例如,同一个文件资源可以被多个应用使用。我可以使用记事本打开一个txt文件,对于这个同样的文件,我可以使用微信进行文件传输。

共享有两种方式:互斥共享方式同时共享方式

  • 互斥共享方式:在同一时刻只能有一个进程使用。一个进程使用完毕后才能分配给下个进程。例如我们在打开一个文件时不能删除这个文件,体现了互斥性。

  • 同时共享方式:系统中的某些资源能够在一个时间段内由多个进程同时访问。

如果失去并发性,那么共享性就毫无意义。失去了共享性,并发性也就无法实现。

虚拟

操作系统具有虚拟性。所谓虚拟就是用户感受和物理实体有所差别,物理实体被分成一个个逻辑上的对应物。常见的例子就是虚拟存储技术和虚拟处理器技术。

例如我的内存有16GB,每个软件打开所占的内存大不相同,每个软件就把内存这个实体分成一个个对应物。即使这些应用所需内存大小超过了我的物理内存,我可以拉上硬盘一起跑这些程序,体现了空分复用的思想。这些程序由CPU处理时是挨个进行处理的,也是一种虚拟,体现了时分复用的思想。

异步

操作系统具有异步性。每个进程执行的速度都不太一样,是不可预知的。原因是并发执行的程序会争夺系统的资源。而资源是有限的,只能等待一个进程使用完毕后才能给下一个进程使用,导致了速度的不可预测。

没有并发和共享,就谈不上虚拟和异步。并发和共享是操作系统中两个最基本的特征。

操作系统的运行机制

一个程序是如何运行的

当我们写代码时,在运行前需要将代码进行编译。这个编译的过程展开有些复杂,后面会专门出一篇去讲。但是我们需要知道的就是这个转换过程会将源代码转换为机器可以识别的二进制指令。当我们运行这个程序,相当于在一行一行运行这个二进制指令。

例如Windows电脑下的exe就是包含二进制数据的程序。

内核程序和应用程序

普通程序员编写的程序都是应用程序。而操作系统的编写者也需要为操作系统的核心编写一个程序,称作为内核(kernel)程序。内核程序是操作系统中最重要最核心的部分,是最接近硬件的部分。操作系统可以删除所有的应用程序还能保持稳定运行,但是删除内核程序则不能运行。

例如操作系统的GUI界面就是应用程序,不属于内核程序。

这里有现成的内核程序的例子,就是开源的Linux操作系统,其代码仓库如下,里面存放的代码就是内核程序:

https://github.com/torvalds/linux

特权指令和非特权指令

程序员写的程序,执行的二进制指令都是非特权指令。这些指令对于安全性的影响较低。与之相对应的,就是特权指令,这种指令程序员和用户都无法使用,只能由内核程序使用。这些指令对于计算机的影响重大,不能轻易使用。

CPU在读取指令时,能够知道正在执行的这条指令是特权指令还是非特权指令。但是CPU并不知道这条指令来自于应用程序还是内核程序。假如说恶意程序在应用程序中添加了特权指令,那CPU还会不会继续运行呢?

内核态和应用态

回答上面的问题,答案是不会。

CPU由两种状态,这种状态的变量存放在程序状态字寄存器(PSW)中。其中有一个二进制位,当为1时表示”内核态“,0表示”用户态“。

当操作系统启动时,CPU首先处在内核态,之后内核程序启动执行特权指令,待系统初始化完毕后,内核程序会向CPU发送一条切换到用户态的特权指令,此时CPU就处于用户态,操作系统中的应用程序开始运行。

假设应用程序向CPU发送了一条特权指令,CPU会分析每个执行的指令,当CPU发现自己处在用户态,却要执行特权指令时,会立刻发出中断(interrupt)。CPU立刻变为核心态,操作系统的处理中断信号的内核程序开始运行。之前运行的应用程序会被强行关闭。

这样的流程保证了普通应用程序不会危害到操作系统的运行。

https://github.com/torvalds/linux/blob/master/arch/x86/entry/entry_64.S

上面的源代码展示了Linux如何处理中断。

中断和异常

中断的作用

  • 内核态切换到用户态:内核程序发出特权指令,用于修改PSW的标志位为用户态。

  • 用户态切换到内核态:由中断引发,CPU从用户态切换到内核态。

可见,中断的作用就是时用户态变为内核态。中断是操作系统夺回CPU使用权的唯一途径

中断又分为不同种,下面来详细解释。

中断的类型

中断可以分为内中断外中断

内中断

内中断与当前执行的指令有关,中断信号来自于CPU内部。内中断也成为异常

上面所讲的应用程序执行特权指令引发了中断,这种中断类型称为终止(abort)。除了故障这一内中断类型,还有其他几种中断类型:

  • 陷入、陷阱(trap):应用程序自发的发出这个指令,将用户态变成内核态。这个指令不是特权指令。

  • 故障(fault):由错误条件引起,处理完错误会将CPU使用权还给应用程序。

  • 终止(abort):执行的指令是特权指令或是指令是非法的(除以0),将引起中断。应用程序被终止运行。

外中断

外中断与当前执行的指令无关,中断信号来自CPU外部,通常由硬件设备产生。外中断也被称为中断。这个中断是与异常相对应的。

  • 时钟中断:操作系统使用时钟中断来跟踪时间,进行时间片调度,为多任务处理分配 CPU 时间。当时钟中断发生时,操作系统可以检查当前正在运行的进程,并决定是否需要切换到另一个进程。这种机制确保了多个进程能够公平地共享 CPU 资源。

  • I/O 中断:由输入/输出设备产生的中断,当 I/O 设备完成数据传输时,它会发送中断信号通知 CPU。这使得操作系统能够及时处理数据,而不必一直轮询设备状态。

中断向量表

不同的中断信号,内核程序运行的子程序也不同。内核程序会根据中断信号的类型查询中断向量表,以此来寻找到中断处理程序在内存中的存放位置。

例如,假设中断向量表的第 5 个元素对应于键盘中断,当键盘输入事件发生时,CPU 会查找中断向量表中的第 5 个元素,找到键盘中断处理程序的地址,并执行该程序。

系统调用

什么是系统调用

前面说过,操作系统在位上层提供服务时,会提供一些接口。系统调用就是操作系统提供给应用程序的接口,可以有程序员调用进行使用。应用程序可以通过系统调用来请求获得操作系统内核的服务

编程语言,例如C++可以将这些系统调用封装成一个个库函数,方便程序员编程使用。

为什么需要系统调用

若两个应用程序并发运行,争夺同一个资源的时候,例如打印机,不经过系统调用直接连接打印机会导致打印机需要同时处理两个请求,通过系统调用,操作系统来决定先后顺序,保证不出错。

操作系统会对共享资源进行统一的管理,程序可以通过系统调用获取到这些资源,若有多个请求则会协调处理

系统调用的分类

graph LR A[系统调用 按功能分类] --> B[设备管理] A --> C[文件管理] A --> D[进程控制] A --> E[进程通信] A --> F[内存管理] B --> B1[完成设备的请求/释放/启动等功能] C --> C1[完成文件的读/写/创建/删除等功能] D --> D1[完成进程的创建/撤销/阻塞/唤醒等功能] E --> E1[完成进程之间的信息传递/信号传递等功能] F --> F1[完成内存的分配/回收等功能]

这些系统调用会穿插在后面的讲解中。

系统调用的过程

应用程序执行系统调用的过程如下:

  1. 传参:应用程序需要将一些参数存放在CPU的寄存器里;

  2. 陷入:应用程序调用陷入指令,CPU转换到内核态;

  3. 中断处理:CPU发现调用的是陷入指令,通过中断向量表执行陷入指令的程序,也就是系统调用入口程序;

  4. 确定处理程序:系统调用入口程序通过寄存器的参数来确定执行哪一个处理程序;

  5. 返回结果:系统调用完成后,内核程序将返回值存在特定寄存器中,执行指令切换到用户态;

  6. 继续:应用程序继续执行。

在高级编程语言中,我们可以用一行或多行代码实现系统调用,这些都封装好了。在转译成二进制指令时,这些调用会自动扩展成上面过程中的指令。

操作系统体系架构

常见的操作系统体系架构如下:

  • 大内核

  • 微内核

还有一些少见的体系结构:

  • 分层结构

  • 模块化

  • 外核

大内核

大内核(Monolithic Kernel)是一种操作系统内核的设计架构,其特点是将操作系统的所有核心功能集成在一个单一的、统一的内核中。我们常见的操作系统例如Windows,Linux都是大内核操作系统。

所有的操作系统服务(如进程管理、内存管理、文件系统、设备驱动等)都运行在内核空间,彼此之间可以直接访问。由于所有服务都在同一内核中,系统调用的开销相对较小,因为不需要在用户空间和内核空间之间频繁切换。

大内核操作系统架构示意图

微内核

微内核(Microkernel)是一种操作系统内核设计架构,其核心理念是将操作系统的基本功能最小化,只保留最基本的服务,而将其他功能(如设备驱动、文件系统、网络协议等)移至用户空间。

微内核操作系统架构示意图

模块化内核

模块化内核结合了大内核和微内核的优点,允许在运行时动态加载和卸载内核模块。这种设计提供了更好的灵活性和可扩展性,同时保持了良好的性能。

分层结构

分层结构是一种系统设计方法,将系统划分为多个层次,每一层负责特定的功能或服务。每一层仅与其相邻的层进行交互,这种设计理念在操作系统、网络协议、软件工程等多个领域中广泛应用。

分层结构操作系统体系架构示意图

外核

外核(Exokernel) 是一种操作系统内核设计理念,旨在提供更高的灵活性和性能。与传统的内核(如微内核或宏内核)不同,Exokernel 的主要目标是将操作系统的功能最小化,并将更多的控制权交给用户空间的应用程序。

对比

类别 优点 缺点
分层结构 1. 便于调试和验证,自底向上逐层调试验证。 1. 仅可调用相邻层,难以合理定义各层的边界。
2. 易扩充和易维护,各层之间接口可随时固定。 2. 效率低,不可跨层调用,系统调用执行时间长。
模块化 1. 模块间逻辑清晰,易于维护,确定模块间接口后即可同步模块同时开发。 1. 模块间接口不必合理,实用。
2. 支持动态加载的内核模块(如:安装设备驱动程序,安装新的文件系统模块到内核),增强OS适应性。 2. 模块间相互依赖,更难调试和验证。
3. 任何模块都可以直接调用其他模块,无需采用消息传递进行通信,效率高。
宏内核(大内核) 1. 性能高,内核内部各功能能直接相互调用。 1. 内核复杂度大,难以维护。
2. 大内核的某个功能模块出错,就可能导致整个系统崩溃。
微内核 1. 只把中断、原语、进程调度等最核心的功能放入内核,进程管理、文件管理、设备管理等功能由用户程序的形式运行在用户态。 1. 性能低,需要频繁的用户态/内核态切换。
2. 用户态的各功能模块不可以直接相互调用,只能通过内核的消息传递来进行通信。 2. 用于系统的各功能模块不可以直接相互调用,只能通过内核的消息传递来进行通信。
外核(exokernel) 1. 内核负责调度,进程管理等分配,不抽象,为用户程序提供尽可能接近硬件的接口,使用用户程序更灵活。 1. 减少了虚拟化资源的“映射层”,提高效率。
2. 使用系统资源得更复杂。

表格来自于王道考研《操作系统》

操作系统引导

当我们打开电源时,操作系统如何启动?

在一开始打开电源,计算机会进行自检并且会打开一个名叫BIOS(基本输入输出系统)的程序,BIOS存放在ROM中,不会随着电源的开启和关闭而擦除。

BIOS加载进RAM中,然后会将硬盘的第一块——MBR(主引导记录)读入内存,接着执行MBR的磁盘引导程序,扫描出分区表。

紧接着,计算机会从主分区的读入分区引导记录PBR,执行其中的程序,这个程序会从根目录下找到操作系统的初始化程序并执行,完成开机。

虚拟机

虚拟机解决了什么问题

假设有这样一台高性能服务器,我需要在上面部署一些应用。就拿两个应用举例吧:

  • 这两个应用间没什么联系,但是需要在同一操作系统中运行。

  • 两个应用需要争抢资源,操作系统没办法固定的为其分配合理资源。另外两个进程并发运行,可能会导致一些安全问题。

  • 一种可行的解决办法是,在不同的服务器上部署不同的应用,但这会造成资源的极大浪费。

基于这个需求,虚拟机是一个不错的选择。虚拟机允许我们在同一硬件上部署不同的操作系统,每个操作系统的环境是独立的,互不影响。

两类虚拟机管理程序VMM

第一类 VMM 第二类 VMM
对物理资源的控制权 直接运行在硬件之上,能直接控制和分配物理资源 运行在 Host OS 之上,依赖于 Host OS 为其分配物理资源
资源分配方式 在安装 Guest OS 时,VMM 要在原本的硬盘上自行分配存储空间,类似于“外核”的分配方式,分配未经过抽象的物理硬件 Guest OS 拥有自己的虚拟磁盘,该盘实际上是 Host OS 文件系统中的一个大文件。Guest OS 分配到的内存是虚拟内存
性能 性能更好 性能更差,需要 Host OS 作为“中介”
可支持的虚拟机数量 更多,不需要和 Host OS 竞争资源,相同的硬件资源可以支持更多的虚拟机 更少,Host OS 本身需使用物理资源,Host OS 上运行的其他进程也需要物理资源
虚拟机的可迁移性 更差 更好,只需导出虚拟机镜像文件即可迁移到另一台 Host OS 上,商用化应用更灵活
执行模式 第一类 VMM 运行在最高权限级(Ring 0),可以执行最高特权的指令 第二类 VMM 部分运行在用户态,部分运行在内核态。Guest OS 发出的系统调用会被 VMM 截获,并转化为 VMM 对 Host OS 的系统调用

0

评论区