操作系统 - 结构与组织

213 阅读11分钟

一、操作系统结构

操作系统1.drawio.png

操作系统的经典组织结构就是如上。分为硬件资源,内核空间和用户空间。
在架构的最上层运行着各种应用程序;内核空间位于硬件资源和用户空间之间,管理硬件资源,提供核心服务。

内核是计算机启动时候,第一个被启动的程序,也是内核中最重要的两个服务是进程管理系统和文件系统。 这里我们先简单的介绍看下内核中比较重要的三个模块:

  • 文件系统
    • 管理文件名、文件内容、目录;理解如何将文件存储在磁盘中;维护独立的命名空间,包含层级目录和文件。
  • 进程管理
    • 每个用户空间程序称为一个进程,拥有自己的内存和共享的CPU时间;管理内存的分配、复用和划分。
  • 访问控制(Access Control)
    • 决定进程是否可以使用某些资源(如读取磁盘数据、使用内存);在分时共享系统中,不同进程可能属于不同用户,访问规则复杂。

在内核中除此之外还有许多服务,包括进程间通信服务,驱动等等。所以一般内核空间会大于用户空间。


(一) 系统调用简要解析

其实从上面我觉得我们可以得出这样的结论:现代操作系统就是围绕用户空间如何和内核空间交互,内核空间如何和硬件资源交互展开的。

我们这里首先从系统调用的角度关注下用户程序和内核间交互如何交互的。

系统调用与程序中的函数调用看起来是一样的,但区别是系统调用会实际运行到系统内核中,并执行内核中对于系统调用的实现。

通过系统调用我们可以修改敏感和被保护的硬件资源。

这里我们以调用名为open的系统调用为例简单看下系统调用的流程:

  1. 文件名作为参数传给open。假设现在要打开一个名为“out”的文件,那么会将文件名“out”作为参数传入。同时我们还希望写入数据,那么还会有一个额外的参数,在这里这个参数的值是1,表明我想要写文件。
  2. 由于 open是一个系统调用,它会跳到Kernel,Kernel可以获取到open的参数,执行一些实现了open的Kernel代码,或许会与磁盘有一些交互。
  3. 返回一个文件描述符对象。之后,应用程序可以使用这个文件描述符作为handle,来表示相应打开的文件。

二、操作系统组织

操作系统需要支持多个活动,例如 fork 的时候,操作系统需要在这些进程之间分配计算机资源。即使在进程数大于 CPU 数的情况下。此外为了一个进程出现 Bug 不会影响其他进程。操作系统必须满足三个条件:多路复用(CPU在多进程同分时复用)、隔离和交互。

(一) 抽象物理资源

操作系统(OS)存在的原因是为了提供一个抽象层,便于管理和使用硬件资源。

1. 操作系统提供的好处

对资源管理与抽象,便于管理和使用硬件资源

文件系统:OS将存储设备抽象为文件系统,应用程序通过open read writeclose等系统调用与文件交互,而不是直接操作磁盘。这为应用程序提供了路径名的便利,并使操作系统能够管理磁盘。

CPU调度OS透明地在进程之间切换硬件CPU,保存和恢复寄存器状态,允许多个应用程序共享CPU,即使某些应用程序陷入无限循环。

内存管理:通过exec系统调用来构建进程的内存映像,允许OS决定进程在内存中的位置,还能在内存紧张时将一些数据存储到磁盘。

为了实现强隔离,OS禁止应用程序直接访问敏感硬件资源,而是将这些资源抽象为服务。

例如,Unix应用程序通过文件系统的系统调用与存储交互,而不是直接读写磁盘。这提供了更好的安全性和隔离。

应用程序间的交互通过文件描述符进行,也简化了交互。例如,管道中的一个应用程序发生故障,内核会为下一个进程生成文件结束信号。

我们再重复一下强隔离的重要性:应用程序不能直接修改或读取操作系统的数据结构和指令,也不能访问其他进程的内存。这可以防止一个应用程序的错误影响整个系统或其他应用程序。

多任务处理:OS通过透明的进程调度,确保CPU资源被公平分配,即使某些应用程序运行时间很长或者出现问题。

如果使用库的方法,每个应用程序都必须定期放弃CPU,以便其他应用程序能够运行。这种协作式分时方案依赖于应用程序的相互信任和无bug,但这种情况不常见。

2. 机器模式、监督模式和用户模式

依赖于 CPU 的支持, RISC-V CPU 提供了机器模式、监督模式和用户模式三种模式。

  • 机器模式:具有完全权限,主要用于系统配置。CPU 启动时处于此模式,xv6 操作系统在执行几行代码后会切换到监督模式。
  • 监督模式:允许执行特权指令,如启用/禁用中断和读写页表地址寄存器等。监督模式下的软件可以执行特权指令,被认为是运行在内核空间。
  • 用户模式:应用程序只能执行普通指令,如数值运算,跳转命令 JRC 等,运行在用户空间。用户模式下应用程序尝试执行特权指令,CPU 不会执行该指令,而是切换到监督模式,以便监督模式代码终止该应用程序。

用户模式与监督模式是怎样转换的呢?

当应用程序需要调用内核函数时,必须从用户模式切换到监督模式。CPU 提供特殊指令(如 RISC-V 的 ecall),将 CPU 从用户模式切换到监督模式,并在内核指定的入口点进入内核。

切换到监督模式后,内核可以验证系统调用参数,检查操作权限,然后决定执行或拒绝操作。

控制进入监督模式的入口点对于内核安全至关重要。如果应用程序能决定入口点,那么恶意应用程序可能会绕过安全检查,直接进入内核,导致系统被破坏。

3. 内核组织

单体内核 (Monolithic Kernel)

整个操作系统都运行在内核空间,拥有所有的硬件访问权限,所有系统调用都在监督模式下执行。

方便操作系统不同部分的协同工作。例如,文件系统和虚拟内存系统可以共享一个缓冲区缓存。

但是一旦在监督模式下发生错误,整个内核可能崩溃

微内核 (Microkernel)

大部分操作系统功能移到用户模式,只保留少量关键功能在内核空间运行。

减少在内核空间运行的代码量,从而降低错误风险。操作系统服务作为用户级进程运行,通过进程间通信机制进行交互。

比如:图2.1中,文件系统作为用户级进程运行,内核提供进程间通信机制,允许应用程序与文件服务器交互。

核心思想

微内核和单体内核操作系统共享许多关键思想:实现系统调用、使用页表、处理中断、支持进程、并发控制和实现文件系统等。

(二) 进程概述

在一般操作系统中,进程是隔离的基本单位,防止一个进程影响其他进程(这也是防止破坏内核的隔离机制的体现)。内核用于实现进程的机制包括用户/监督模式标志、地址空间和线程的时间片切换。

进程为程序提供了一个独立的内存系统(地址空间)和一个独立的CPU执行环境,使程序看起来像运行在独立的机器上。进程抽象可以防止一个进程破坏或监听另一个进程的的内存(页表)、CPU(寄存器)、文件描述符等资源。

所以说,进程结合了地址空间和线程两个设计理念,提供独立的内存和CPU假象。

每一个进程中存储着哪些内容?

  1. 页表与地址空间
    • 使用硬件实现的页表为每个进程提供独立的地址空间。也就是说每个进程维护一个独立的页表,定义其地址空间。
    • RISC-V 页表将虚拟地址(RISC-V 指令操作的地址)映射到物理地址(CPU 发送到主存的地址)。
  1. 内核状态
    • xv6为每个进程维护多个状态信息,存储在struct proc结构体中。
    • 包括页表、内核堆栈和运行状态等。用 p->xxx 表示 proc 结构体的元素,例如 p->pagetable 是指向进程页表的指针。
  1. 线程和堆栈
    • 每个进程有一个控制线程,保存执行进程所需的状态。
    • 每个进程有两个堆栈:用户堆栈和内核堆栈。执行用户指令时使用用户堆栈,进入内核时使用内核堆栈。
      • 当进程执行用户指令时,仅使用其用户堆栈,内核堆栈为空。
      • 当进程进入内核(进行系统调用或中断)时,内核代码在进程的内核堆栈上执行;当进程在内核中时,其用户堆栈仍包含保存的数据,但不被积极使用。
      • 进程的线程在使用其用户堆栈和内核堆栈之间交替。
      • 内核堆栈是独立的(并受到用户代码保护),即使进程破坏了其用户堆栈,内核也能执行。
  1. 进程状态
    • p->state指示进程的状态:已分配、准备运行、正在运行、等待I/O或退出。
    • p->pagetable保存进程的页表,用于记录进程内存的物理页面地址。

(三) 系统调用再次简述

我们现在知道必须要有一种方式可以使得用户的应用程序能够将控制权以一种协同工作的方式转移到内核,这样内核才能提供相应的服务。

RISC-V 中有一个专门的命令称为 ecall<n>来实现这个功能。

当我们使用系统调用函数的时候,实际上调用的是 ecall,ECALL 接收一个数字参数,这个参数就代表了应用程序想要调用的 SystemCall。

那从现在我们现在学到的来看系统调用又是怎么一回事呢?

从用户态到内核态:通过执行RISC-V ecall指令发起系统调用,提高硬件特权级别,将程序计数器更改为内核定义的入口点(内核的一个特定的由内核控制的位置),入口点代码切换到进程的内核堆栈并执行实现系统调用的内核命令。

从内核态返回用户态:系统调用完成时,内核切换回用户堆栈并通过调用 sret 指令返回用户空间,该指令降低硬件特权级别并恢复执行紧接系统调用指令之后的用户指令。进程的线程可以在内核中“阻塞”以等待 I/O,当 I/O 完成时从停止的位置恢复。

这里我们因为没有设计到 Trap 机制,关于系统调用就先到此为止。我们到此已经引出了 ECALL 和为什么需要系统调用和系统调用的大致流程。

参考资料:

pdos.csail.mit.edu/6.828/2024/… MIT6.1810 2024相关资料