操作系统概念

概念

操作系统 是计算机系统中的一个核心软件组件,负责管理和控制计算机硬件,为用户和应用程序提供服务。

操作系统特征

  1. 并发(Concurrence):操作系统 具备同时处理和调度多个程序的能力。
  2. 共享(Sharing):系统中的资源可供内存中多个并发的进程共同使用。
  3. 虚拟(Virtual):将物理的实物虚拟为逻辑上的对应物。
  4. 异步(Asynchronism):任务可以不按固定的顺序执行,因此同一操作的结果可能因执行的时序而异。

注意:并发共享 是 OS 的两个最基本的 特征

并发

共享

[互斥共享]

共享资源:临界资源

[同时共享]

虚拟

异步

异步的过程是 根据 资源的是否可用 决定是否运行的   没有时钟催着它执行任务 

作业 == n 个进程

目标和功能

  • 作为用户语句计算机硬件系统之间的接口。
  • 作为计算机系统资源的管理者。
  • 实现了对计算机资源的抽象。

相当于外面包了一层皮,你看到的东西不是机械,而是一个

发展历程

操作系统 的发展历程经历了 手工操作、批处理操作、分时操作、实时操作 这四个阶段:

  1. 手工操作 阶段:

    • 时间背景:计算机的早期阶段。
    • 特点:没有 操作系统,用户直接使用计算机硬件。
    • 操作方式:用户在一个时刻将自己的程序载入计算机,然后执行。执行完毕后,将结果记录并释放计算机。
    • 问题:效率低,CPU 大部分时间处于空闲状态。
  2. 批处理操作系统

    • 单道批处理系统
      • 特点:系统一次只执行一个任务。完成后再执行下一个。
      • 操作方式:用户的多个作业被收集到一个作业队列中,操作系统 按照队列的顺序逐一执行。
      • 问题:CPU 利用率仍然不高,因为在 I/O 操作时,CPU 仍然处于空闲状态。
    • 多道批处理系统
      • 特点:在内存中同时加载多个作业,并使它们共享 CPU
      • 操作方式:当一个作业进行 I/O 操作时,CPU 可以切换到另一个作业,从而提高了 CPU 的利用率。
      • 优势:提高了系统吞吐量和 CPU 利用率。
  3. 分时操作系统

    • 时间背景:20 世纪 60 年代。
    • 特点:允许多个用户通过终端同时访问计算机。
    • 操作方式:操作系统 为每个用户提供了一个“虚拟机”的概念,使每个用户感觉自己独占了整个系统。实际上,系统在用户之间快速切换,为每个用户提供少量的 CPU 时间。
    • 优势:提高了交互性和多用户并发访问的能力。
    • 示例:Unix 操作系统在其初期就是一个分时系统。
  4. 实时操作系统

    • 特点:系统必须在严格的时间限制内响应外部输入。
    • 分类:
      • 硬实时系统:不满足时限会导致严重的后果,如飞行控制系统。
      • 软实时系统:不满足时限可能会降低系统的性能,但不会导致灾难,如多媒体播放器。
    • 操作方式:实时 操作系统 的任务调度是基于优先级的,且通常会预先定义每个任务的执行时间。
    • 优势:满足特定应用场景的实时需求,如嵌入式系统和工业控制系统。

操作系统引导

引导流程

操作系统 引导的具体流程如下:

  1. 电源开机(Power-On):

    • 当你按下计算机的电源键时,电源开始向主板和各个硬件供电。此时,系统首先进行加电自检。这个过程是由存储在主板 ROM 芯片中的基本输入/输出系统(BIOS)或统一可扩展固件接口(UEFI)固件执行的。
  2. BIOS/UEFI 阶段

    • BIOS/UEFI 会读取启动设备的首扇区(MBR 或 GPT),其中包含 引导加载器(Bootloader)的代码。
  3. 引导加载器(Bootloader):

    • 引导加载器 是一小段程序,它的主要任务是加载 操作系统 内核。
    • 常见的 bootloader 有
      • GRUB(Grand Unified Bootloader):常用于 Linux 系统,功能强大,支持多系统引导。
      • Windows Boot ManagerWindows 操作系统的引导管理器。
    • 引导加载器 会将 操作系统 内核从存储设备(通常是硬盘)加载到内存中。
  4. 加载操作系统内核

    • 操作系统 内核是 操作系统 的核心部分,负责管理系统的各种资源,如内存、进程、设备等。引导加载器 将内核加载到内存后,会将控制权交给内核。
  5. 内核初始化

    • 操作系统 内核开始运行并进行自我初始化。它会检测和配置系统上的硬件资源,例如设置中断、初始化设备驱动、建立内存管理结构等。
  6. 启动系统服务和守护进程

    • 在内核初始化后,它会启动一系列的系统进程或服务来管理各种系统任务。

注意

引导程序并不是全部都调入到主存中的,只取出其内核部分调入

程序运行环境

⭐中优先级

这一节选择题还是经常考察的,重点在于理解 用户态和内核态 以及 系统调用 这两个概念,程序的链接和装入相对考察频率比较低。

原语

一条原语 处于 操作系统最底层, 由 多条指令构成,不能被打断,运行时长较短,调用频繁

CPU 运行模式

CPU的两种 运行模式内核模式(又称为特权模式、系统模式或超级用户模式)和 用户模式 是操作系统设计中用于隔离系统关键任务与普通任务的机制,以提高系统的安全性和稳定性。

注意

用户态/内核态到底是操作系统还是 cpu 的模式?

大多数现代 CPU(如 x86、ARM)都有多级 权限(ring 0~ring 3),通常:

  1. Ring 0内核态):可执行一切指令,访问所有硬件资源。
  2. Ring 3用户态):受限,只能执行普通指令,无法直接操作硬件或访问内核数据结构。

所以,内核态/用户态 本质上 是 CPU 的运行权限级别,是硬件提供的机制。

但操作系统是这个机制的“使用者”和“管理者”,操作系统借助这套机制实现进程隔离、安全保护、系统调用等功能。

内核模式

内核模式(Kernel Mode)是操作系统内核运行的环境,具有 最高权限,能够直接访问硬件和所有系统资源。

特点

  • 完全权限:内核模式下的代码可以直接操作硬件(如CPU、内存、I/O 设备等),执行特权指令。
  • 核心功能:操作系统内核负责管理进程、内存、文件系统和设备驱动等核心功能,这些都在内核模式下完成。
  • 上下文切换:用户模式程序通过系统调用进入内核模式,完成操作后返回用户模式。
  • 高风险:内核模式的错误可能导致系统崩溃,因此需要极高的稳定性。

[特权指令] 

特权指令(Privileged Instruction)是指在计算机系统中只能由操作系统 内核态下 的程序执行的特殊指令。这些指令通常涉及对硬件资源或系统关键功能的直接控制,具有较高的权限,常见的特权指令包含如下类型:

  • 硬件控制:如设置中断使能、修改处理器状态寄存器。
  • 内存管理:如修改页表、设置内存保护。
  • 进程管理:如创建或终止进程、更改进程优先级。
  • I/O 操作:直接访问硬件设备或端口。
  • 系统调用相关:如切换到内核态以执行系统服务。

注意

中断屏蔽字寄存器(可屏蔽中断)属于中断控制器的一部分,而中断控制器又是属于 I/O 接口的,因此设置中断屏蔽字 相当于对 I/O 接口中的 I/O 端口进行设置,属于 I/O 指令

用户模式

用户模式(User Mode)是普通 应用程序 运行的环境,运行在 受限的权限级别。用户程序(如浏览器、文本编辑器等)通常在此模式下运行。

特点

  • 权限受限:用户模式下的程序无法直接访问硬件或核心系统资源(如内存、CPU 寄存器等),需要通过系统调用(System Call)请求操作系统服务。
  • 隔离性:每个用户程序运行在自己的地址空间,相互隔离,防止程序直接干扰其他程序或系统。
  • 安全性:由于权限受限,用户程序的错误(如崩溃)通常不会直接影响操作系统。
  • 执行方式:用户程序通过调用库函数或API间接与操作系统交互。

用户模式和内核模式是操作系统实现安全性和稳定性的核心机制。用户模式提供隔离和安全的环境运行应用程序,而内核模式负责核心资源管理和特权操作。两者通过系统调用等机制协作,共同完成计算任务。

用户可以通过 中断 异常 向 OS 请求 操作系统内核 提供 服务,

例如:有意识地使用 (访管指令 属于异常) 这个指令是在用户态执行的

一定要区分 调用指令 和 执行指令 这两个指令分别在那种运行模式下。

系统调用

系统调用(system call)是运行在用户模式的应用程序与操作系统内核之间的 接口。当应用程序需要执行一些它在用户模式下不能直接完成的任务(如文件操作、网络通信、创建进程等)时,它可以通过系统调用来请求操作系统内核在内核模式下为其执行这些操作。

系统调用的过程如上图所示,从用户态进入内核态,完成后再返回用户态:

  • 当用户程序执行系统调用(或触发中断)时,CPU 会自动 切换到内核态,这时控制权就交给了操作系统。
  • 操作系统执行完后,再通过特定指令(如iret, sysret, eret)切回用户态

特点

  • 特权级的转换:应用程序通常在用户模式下运行,而操作系统内核在内核模式下运行。系统调用提供了从用户模式到内核模式的一种安全的转换机制,这样内核可以代表应用程序执行特权操作。
  • 系统调用的类型:常见的系统调用类型包括进程管理(如创建、终止进程)、文件操作(如打开、读取、写入、关闭文件)、网络通信、设备控制、内存管理等。
  • 性能开销:执行系统调用涉及上下文切换,从用户模式到内核模式,然后再返回。这会带来一定的性能开销。因此,频繁地进行系统调用可能会影响应用程序的性能。

举个实际的 x86 例子

  1. 用户程序执行 int 0x80(系统调用指令);

  2. CPU 自动:

    • 切换到 Ring 0(即内核态);
    • 跳转到操作系统设定的系统调用处理函数;
  3. 操作系统执行相关服务;

  4. 执行 iret 返回用户程序;

  5. CPU 自动:

    • 切回 Ring 3(即用户态);
    • 恢复用户程序继续运行。

系统使用库函数(并非真正的 系统调用)请求OS的服务

异常处理:

中断处理看 计组 输入输出设备

过程调用

过程调用 也被称为 子程序调用 或 函数调用

具体操作看图

它允许程序代码被组织成块,每个块完成特定任务,可在程序的多个地方被调用

对比

过程调用没有引发中断(不需要切换运行态),而系统调用是通过发起一个软中断实现调用 OS 内核代码

过程调用 在调用 时 只需要保存PC 而不需要保存 PSW(因为这是系统主动进行的)
而系统调用需要正常的进行(内部)中断处理,因此需要保存 PC 和 PSW

注意

过程调用全程 CPU 都处于同一个工作模式,即用户态或 内核态

而系统调用会导致 CPU 从用户态切换到内核态

过程调用 的被调用函数 在代码中,但是系统调用通过库函数实现,是不在程序代码中的

过程调用可以嵌套,但系统调用一般 不允许发生嵌套 或递归 重点

程序的链接

程序的链接是将编译后的代码模块(通常是目标文件)和其他所需的库组合在一起,生成一个可以执行的程序或库的过程。链接过程由 链接器(linker)完成。

根据所使用的库的链接方式,链接可以分为 静态链接 和 动态链接

  • 静态链接

    • 当使用静态链接时,外部代码和库在链接阶段就被 整合到最终的可执行文件中。这意味着,如果程序使用了某个库的函数,那么这些函数的代码会被复制到最终的二进制文件中。
    • 结果是一个较大的可执行文件,因为它包含了所有必要的代码以独立运行。
  • 动态链接

    • 使用动态链接时,外部库不会被直接嵌入到最终的可执行文件中。相反,程序包含了对动态链接库(如 Linux 中的.so 文件或 Windows 中的.dll 文件)的引用。当程序启动时,这些库会被 动态加载 到内存中供程序使用。
    • 动态链接的库通常称为动态链接库(Dynamic Link Libraries,DLL)或共享对象(Shared Object)。

静态链接

简单来说,对于 静态链接依赖 直接作为 二进制 被打包进最后的 可执行程序 中,所以可以直接 跨机器运行(当然操作系统得一样)。

动态链接

对于 动态链接,程序只保存依赖的库地址,依赖与可执行程序 分开保存,当程序执行时再去 动态地加载依赖库。对于动态链接,拷贝可执行程序到另一台机器不一定能直接运行,这需要另外一台机器也保存有相应依赖。

两者的区别如下表所示:

特点/链接方式静态链接动态链接
文件大小通常较大,因为库代码被整合到可执行文件中通常较小,只包含对库的引用
运行依赖不需要外部库文件需要相应版本的动态链接库文件
存储效率较低,每个程序都有库的一个副本较高,多个程序共享同一个库文件
更新便利性较差,更新库需要重新链接和分发程序较好,只需更新库文件
启动性能通常更快,无需加载外部库可能稍慢,需要加载外部库
跨版本兼容性较好,因为程序包含了特定版本的库代码可能出现问题,特别是当库接口发生变化时
这里跨版本说的是当前电脑内的库更新了,但是对应(静态链接)可执行文件中装入的库文件是旧版本的(与世无争),所以兼容性好;但是对于动态链接来说,没有对应的新库的外部链接,代码就不能使用了!!!

程序的装入

程序的装入是指将程序或进程的代码和数据从 磁盘 加载到 主存(RAM)中的过程,使其准备好被 CPU 执行。装入过程在程序执行周期中是必不可少的一部分,通常由操作系统中的 装入器(loader)完成。

绝对装入

适用于 单道程序环境。在编译时,若知道程序驻留在内存的某个位置,则编译程序将产生绝对地址的目标地址。绝对装入程序按照装入模块的地址,将程序和数据装入内存。由于程序中的逻辑地址与实际地址完全相同,因此不需要对程序和数据的地址进行修改。

另外,程序中所用的绝对地址,可在编译或汇编时给出,也可由程序员直接赋予。而通常情况下在程序中采用的是符号地址,编译或汇编时在转换为绝对地址。

(静态)可重定位装入

在 多道程序环境 下,多个目标模块的起始地址通常都从 0 开始,程序中的其他地址都是相对于起始地址的,此时应采用可重定位装入方式。根据内存的当前情况,将装入模块装入内存的适当位置。在装入时对目标程序中 指令 和 数据 地址的修改过程称为 重定位,又因为地位变换通常是 在进程装入时 一次完成的,故称为 静态重定位

当一个作业装入内存时,必须给它分配要求的全部内存空间,若没有足够的内存,则无法装入。此外,作业一旦装入内存,整个运行期间就不能在内存中移动,也不能再申请内存空间。

动态运行时装入

也称为 动态重定位。装入程序把装入模块装入内存后,并不立即把装入模块的相对地址转换为绝对地址,而是把这种地址转换推迟到程序真正要执行时进行。因此,装入内存后的所有地址都是相对地址。这种地址需要一个重定位寄存器的支持。

注: 这里 重定位寄存器

动态重定位的优点在于可以将程序分配到不连续的存储区;在程序运行之前可以只装入部分代码即可运行,然后在程序运行期间,根据需要动态申请分配内存

这里 动态重定位的 思想确实和 基址寻址的做法 如出一辙

1. PC给出逻辑指令地址
2. 动态重定位
3. 得到物理指令地址
4. 取出指令
5. 分析指令中的操作数地址
6. 再次地址变换
7. 得到物理数据地址
8. 访问数据

但是要注意两者的区别,实际上装入后 重定位的 物理地址对应的是 一个指令,随后该指令通过对应的 寻址方式,找到对应的数据

理顺工作逻辑,就不会混为一谈了

操作系统结构

💡低优先级

偶尔在选择题中考一下 宏内核和微内核 以及 虚拟机 的概念。

分层和模块化

操作系统的设计和结构在历史上经历了多种不同的方法和技巧,为了增加 可维护性灵活性 和 可扩展性分层 和 模块化 是操作系统设计中两种主要的技术方法。

  • 分层结构

    • 概念:在分层的操作系统中,系统被划分为多个层次或“层”,每层都为其上一层提供服务,并依赖于其下一层的功能和服务。

    • 优点

      • 每层只需与其直接的上下层进行交互,简化了设计和调试。
      • 提高了灵活性,因为改变某一层的实现不会影响到其他层。
      • 有助于保护和安全性,因为较低的层(如硬件访问层)被封装起来,上层代码不能直接访问。
    • 缺点:

      • 合理定义各层比较困难(例如文件管理、内存管理等 都在一个层次)
      • 不够灵活,效率极差

  • 模块化结构

    • 概念:模块化操作系统基于模块的概念,每个模块都有一个特定的功能,各个模块之间的交互通过定义良好的接口进行。模块化与面向对象编程中的封装和抽象概念类似。

    • 优点

      • 易于维护和更新。如果某个模块需要更改或修复,可以独立于其他模块进行。

      • 提高了可扩展性。新的功能或模块可以相对容易地添加到系统中。

      • 增加了系统的可靠性和稳定性,因为每个模块的功能都被限定在明确的边界内。

内核架构

微内核

微内核(microkernel)是一种最小化的内核设计,只保留最核心的功能(如线程管理、虚拟内存、进程间通信等)在内核态运行,其他功能(如文件系统、设备驱动、网络协议栈等)以用户态服务的形式运行。

  • 特点

    • 只有最基本的服务(进程和线程管理、低级存储器管理、中断处理)运行在 内核态
    • 其他服务,如设备驱动、文件系统等,作为 用户空间 的独立进程运行。
    • 内核和服务间通过消息传递进行通信。
  • 优点

    • 更高的系统可靠性

    • 稳定性高,用户空间的服务(如驱动程序)如果崩溃,不会影响整个系统(提供了对 分布式系统 的支持)。

    • 更加灵活,允许在运行时更改或添加服务(增强了系统的可移植性)。

    • 更容易扩展和维护。

    • 融入了面向对象技术

  • 缺点

    • 由于需要频繁的上下文切换和消息传递,通常 性能会稍逊于宏内核
  • 示例:IOS 、谷歌的Fuchsia和 HarmonOS NEXT 都是基于微内核的系统。

Hint

精华留在内核,次要程序放到外面执行,给予用户更大的权限

其设计原则:“机制与策略分离”
根据该设计原则划分,进程管理、存储器管理和 I/O 管理等功能均被分解为两部分:极值保留在微内核中,策略则由外部服务器实现。

宏内核

宏内核(monolithic kernel)将所有操作系统功能集成在一个大的内核程序中,运行在内核态。

  • 特点
    • 在单一的地址空间中运行大部分系统服务,如设备驱动、文件系统、网络协议等。
    • 所有的内核服务都运行在 内核态
  • 优点
    • 由于所有的服务都在同一个地址空间中运行,因此服务间的通信较快。
    • 传统上,宏内核系统比微内核系统性能更高。
  • 缺点
    • 如果内核中的一个部分失败,整个系统都可能崩溃
    • 随着功能的增加,内核可能会变得臃肿,导致维护困难。
  • 示例:传统的 UNIX 系统、Linux 、Windows、Android 都是基于宏内核或混合内核。

外核

说实话外核的理念就是尽量让 内核的空间积压到极小,

感觉和 微内核的说法一样啊 ??

虚拟机

虚拟机(Virtual Machine, VM)是一种通过软件模拟真实计算机功能的 虚拟化技术,能够在一台物理主机上创建多个独立的虚拟计算机环境。每个虚拟机都具备与真实硬件相似的运行环境,可以运行独立的操作系统和应用程序,仿佛它们运行在专属的物理设备上。这种技术广泛应用于服务器整合、测试开发、跨平台应用等场景。

1型虚拟机管理程序

客户机的内核态 可以通过 VMM 这个 真正的内核态 管理程序 间接的 使用硬件资源

2型虚拟机管理程序

虚拟机监视器

Hypervisor,也称为虚拟机监视器(Virtual Machine Monitor, VMM),是 虚拟化技术 的核心组件,运行在物理主机和虚拟机之间的中间软件层。它负责协调和管理多个虚拟机,使它们能够共享底层 物理硬件资源,同时保持彼此 隔离。Hypervisor 的主要职责包括:

  1. 创建与管理虚拟机:为每个虚拟机分配独立的 虚拟化硬件资源(如 CPU、内存、存储和网络)。
  2. 硬件资源抽象:通过虚拟化技术,Hypervisor 将 物理硬件资源抽象化,使每个虚拟机认为自己独占硬件资源,从而运行独立的操作系统。
  3. 隔离与安全:确保虚拟机之间的运行互不干扰,增强系统安全性。

Hypervisor 的特权级

Hypervisor 通常运行在比操作系统更高的 特权级(如硬件虚拟化支持的 VMX root mode 或 Ring -1),以便有效管理虚拟机及其资源。相比之下,虚拟机中的操作系统通常运行在较低的特权级(如 Ring 0)。这种特权级差异确保 Hypervisor 能够完全控制硬件资源并协调多个虚拟机的运行,而不会与虚拟机中的操作系统发生冲突。

注意

特权级如何理解?

特权级是处理器提供的抽象概念,现代处理器(如 x86、ARM)通过硬件支持不同的 特权级别(Privilege Levels),以区分操作系统、应用程序和更底层的管理程序的执行权限。这些级别通常通过“环”(Rings)或类似的模式划分:

  1. Ring 0:操作系统内核运行的级别,具有最高权限,可以直接访问硬件资源(如 CPU、内存)。
  2. Ring 1~3:用户态应用程序运行的较低权限级别,无法直接操作硬件。
  3. 虚拟化扩展:现代处理器引入了更高权限的模式(如 x86 的 VMX root mode 或 ARM 的 EL2),专为虚拟机监视器(Hypervisor/VMM)设计。

总结

第一章中常考的 知识点,程序运行在什么用户模式下?

实际上,考量其运行在什么态之下 的唯一标准是:其有无执行(xx)指令的能力

特殊一点,对于 1 型 VMM 管理程序,其本身属于 用户态 的程序,但是又可以间接的调用硬件资源,因此对于其处于何种工作模式,无法一元论之,所以说,重点是看他的实际运行