操作系统看这一篇就够了(万字长文)

操作系统

(注:文章末尾附有参考文章以及部分内容的具体细节)

目录

  • 操作系统
    • 一、概述
    • 二、计算机硬件
      • 1、CPU
        • 1、主要任务
        • 2、CPU的执行周期
        • 3、CPU的构成
        • 4、寄存器
        • 5、现代CPU的设计
        • 6、CPU的两种模式
        • 7、状态的切换
      • 2、多线程和多核芯片
        • 基本概念
        • 多线程和超线程
      • 3、内存
        • 1、寄存器
        • 2、高速缓存
          • L1Cache
          • L2Cache
          • L3Cache
          • 时钟周期
        • 3、主存
        • 4、磁盘
          • 普通磁盘
          • 固态硬盘(SSD)
          • 虚拟内存
          • MMU
      • 4、I/O设备
          • 设备控制器
          • 设备驱动程序
          • 设备寄存器(I/O端口)
          • 访问端口的两种方式
          • 输入输出的三种方式
      • 5、总线
      • 6、计算机启动过程
        • 主板
        • BIOS
        • CMOS
        • MBR
        • 启动过程
    • 三、操作系统结构
      • 1、单体系统
      • 2、库文件
        • 1、静态链接库
        • 2、动态链接库
        • 3、区别
      • 3、分层系统
      • 4、微内核
    • 四、操作系统的类型
      • 1、大型机操作系统
      • 2、服务器操作系统
      • 3、多处理器操作系统
      • 4、掌上计算机操作系统
      • 5、嵌入式操作系统
      • 6、传感器节点操作系统
      • 7、实时操作系统
      • 8、智能卡操作系统
    • 五、操作系统概念
      • 1、进程
        • 地址空间
        • 进程控制块(PCB)
        • 上下文切换
        • 进程与线程
      • 2、文件系统
        • 特殊文件
      • 3、保护
      • 4、系统调用(UNIX)
        • 进程管理的系统调用
          • fork()
          • execve(name,argv,env)
        • 文件管理的系统调用
          • iseek(fd,offset,whence)
          • stat(name,&buf)
        • 目录管理的系统调用
        • 其他系统调用

一、概述

现代计算机系统的组成

​ 处理器、主存、键盘、鼠标、显示器、网络接口、输入/输出设备

操作系统

  • 作用:通过响应用户输入的指令达到控制硬件的效果,从而满足用户需求
  • 任务:为用户程序提供更简单、更清晰的计算机模型
操作系统看这一篇就够了(万字长文)_第1张图片

二、计算机硬件

简单个人计算机的组件如下图所示

操作系统看这一篇就够了(万字长文)_第2张图片

简单电脑可抽象为上图的模型,CPU、内存和IO设备都和总线相连,并且通过总线与其他设备进行通信

1、CPU

1、主要任务

​ 与内存进行交互

2、CPU的执行周期

​ 一个CPU的执行周期分为三步

  1. 从内存中提取指令

  2. 解码,决定其类型和操作数

  3. 执行指令

3、CPU的构成

​ 运算器、控制器、寄存器组、内存总线

4、寄存器

​ 寄存器分为通用寄存器与特殊寄存器,通用寄存器一般用于存放变量和临时结果。

​ 部分特殊寄存器如下所示:

  • 程序计数器:存放内存中下一条指令的地址

  • 堆栈指针:指向内存中栈的顶端,包含输入过程中的有关参数,局部变量以及没有保存在寄存器中的临时变量

  • PSW(程序状态寄存器):跟踪当前系统的状态

    每次当操作系统停止运行一个程序的时候,就会保存所有寄存器中的值,以便下一次重新运行该程序

5、现代CPU的设计

  • 流水线设计

    优点:可以同时读取多条指令

    eg. 当 CPU 执行第 N 条指令时,还可以对 N + 1 条指令解码,还可以读取 N + 2 条指令

    操作系统看这一篇就够了(万字长文)_第3张图片
  • 超标量CPU设计

    特点1:存在多个执行单元,只要一个执行单元空闲,就会去检查缓冲区是否有可以执行的指令。如果有,就把指令从缓冲区中取出并执行。

    特点2:这种设计的含义是应用程序通常是无序执行的。在大多数情况下,硬件负责保证这种运算的结果与顺序执行指令时的结果相同。

    eg. 多个执行单元,一个用来进行整数运算、一个用来浮点数运算、一个用来布尔运算。

操作系统看这一篇就够了(万字长文)_第4张图片

6、CPU的两种模式

PSW 寄存器中的一个二进制位会控制当前状态是内核态还是用户态

  • 内核态:CPU可以执行指令集的任何指令,能够使用硬件的功能
  • 用户态:CPU可以执行指令集的部分指令,能够使用硬件的部分功能

7、状态的切换

​ 为了获取操作系统的服务,用户程序必须使用系统调用(system call),系统调用会将用户态转换为内核态并且调用操作系统,TRAP指令用于处理这个操作。

​ 需要注意的是操作系统在进行系统调用时会存在陷阱。大部分的陷阱会导致硬件发出警告,比如说试图被零除或浮点下溢等。在所有的情况下,操作系统都能得到控制权并决定 如何处理异常情况。有时,由于出错的原因,程序不得不停止。

2、多线程和多核芯片

Intel Pentinum 4也就是奔腾处理器引入了被称为多线程超线程的特性。

多线程允许 CPU 保持两个不同的线程状态并且在纳秒级(nanosecond) 的时间完成切换。(1ns = 10 ^(-9)s )

基本概念

物理CPU
物理CPU就是插在主机上的真实的CPU硬件。

核心数
单块CPU上面能处理数据的芯片组的数量。多内核(multicore chips)是指在一枚处理器(CPU)中集成两个或多个完整的计算引擎。双核就是包括2个相对独立的CPU核心单元组.

逻辑CPU
假如物理CPU不支持超线程的,那么逻辑CPU的数量等于核心数的数量;如果物理CPU支持超线程,那么逻辑CPU的数目是核心数数目的两倍。

同步

发送方发送数据后,等接收方发回响应后才发送下一个数据包的通讯方式

异步

发送方发送数据后,不用等接收方发回响应,直接发送下一个数据包的通讯方式

CPU的核心数和线程数量的关系

处理器核数(包含超线程数)是一种执行资源, 资源数量就是核数个数。应用程序的进程数就是服务请求数,操作系统的作用就是如何用有限的资源服务好应用程序的请求,这也就是进程调度的功能。

一般情况下,线程会 “相对公平” 地分配到核上运行,并且在时间片上轮流使用,并发执行(不一定是并行)。

eg. 系统有4个核,如果

  1. 只有3个线程,那就分配到3个核上运行
  2. 只有8个线程,那就每个核分配两个线程运行
  3. 只有10个线程,那就有的核跑3个线程,有的跑2个

但这种分配并非是绝对的,要看应用程序采取的是什么样的调度策略,操作系统会尽量让每个线程的平均等待时间最小化。

多线程和超线程

多线程技术

  • 原理:假设现在有一个CPU,运行两个线程,这两个线程在CPU内部其实是串行处理的。CPU在两个线程中相互切换,使得宏观上两个线程看起来处于并行状态。

  • 优点:提高CPU的利用率(比如CPU只有一个线程的话,线程处于等待状态,CPU就空闲了)

  • 缺点:线程间切换需要一定开销(无限制的加大线程数会带来线程切换的开销)

超线程技术

  • 原理:超线程技术可以让系统误以为系统内有两块物理CPU,操作系统就会向CPU发送2个线程的任务。CPU将会尝试同时执行两个线程,这两个线程使用一个CPU上的不同执行单元,这样就真正实现了两个线程的并行操作。
  • 原因:一个线程在执行时会独占CPU资源,其他线程想要得到执行就必须等待该线程将CPU资源让出。利用超线程技术,让两个线程同时占用CPU资源,这样可以减少很大部分的多线程切换操作。
  • eg. 有个单核的CPU,想要运行一个多线程的程序,通常情况下,只能是由CPU在线程之间来回调度,但是当开启了超线程之后,**可以在一个线程执行整数指令集的时候,另一个线程执行浮点指令集,而这两个指令集由整数指令单元和浮点指令单元来执行。**这样就实现了同时执行两个线程,这就叫超线程。

多线程与超线程的本质区别

  • 多线程不会提供真正的并行处理,而超线程可以

3、内存

存储层次结构图如下图所示

操作系统看这一篇就够了(万字长文)_第5张图片

1、寄存器

存储器的顶层是 CPU 中的寄存器,它们用和 CPU 一样的材料制成,所以和 CPU 一样快。程序必须在软件中自行管理这些寄存器(即决定如何使用它们),一般0个时钟周期就可以访问到数据。

2、高速缓存

  • 目的:为了解决CPU运算速度与内存读写速度不匹配的矛盾

  • 原理:当CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就到内存中读取并送给CPU处理,同时读取足够的字节来填入高速缓存行(相邻数据)。

  • 组成:缓存由缓存行组成,不同的CPU,高速缓存行大小不同,并且始终在第32个字节或64个字节处对齐

  • 架构:CPU缓存可以分为一级缓存L1,二级缓存L2,部分高端CPU有三级缓存L3,每一级缓存中所储存的全部数据都是下一级缓存的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以它的容量也是相对递增的。

    操作系统看这一篇就够了(万字长文)_第6张图片
L1Cache

一级缓存分为一级数据缓存(L1d)和一级指令缓存(L1i),一般CPU的L1i和L1d具备相同的容量,分别用于存放数据及执行数据的指令解码,两者可同时被CPU访问,减少了CPU多核心、多线程争用缓存造成的冲突,提高了处理器的效能。

L2Cache

主要作用是在CPU未命中L1的情况下继续在L2寻求命中,现在也集成在CPU内部

L3Cache

主要提升了处理器大数据处理方面的性能

时钟周期

时钟周期是振荡器两个脉冲之间的时间量,计算机处理器或 CPU 的速度由时钟周期来确定。一般而言,每秒脉冲数越高,计算机处理器处理信息的速度就越快。时钟速度以 Hz 为单位测量,通常为兆赫(MHz)或千兆赫(GHz)。例如,一个4 GHz处理器每秒执行4,000,000,000个时钟周期。

计算机处理器可以在每个时钟周期执行一条或多条指令,这具体取决于处理器的类型。现代处理器在每个时钟周期可以执行多条指令。

3、主存

主存通常叫做 RAM(Random Access Memory),一般使用动态半导体存储器件(DRAM)

除了主存之外,许多计算机还具有少量的非易失性随机存取存储器。它们与 RAM 不同,在电源断电后,非易失性随机访问存储器并不会丢失内容。ROM中的内容一旦存储后就不会再被修改。在计算机中,用于启动计算机的引导加载模块就存放在 ROM 中。另外,一些 I/O 卡也采用 ROM 处理底层设备控制。

EEPROM(Electrically Erasable PROM,)闪存(flash memory) 也是非易失性的,但是它们可以擦除和重写。不过重写它们需要比写入 RAM 更多的时间。

闪存通常用来作为便携性的存储媒介。闪存可以是数码相机中的胶卷,便携式音乐播放器的磁盘。闪存的速度介于 RAM 和磁盘之间。另外,与磁盘存储器不同的是,如果闪存擦除的次数太多,会出现磨损。

4、磁盘

普通磁盘

磁头、磁道、柱面、扇区、盘片

硬盘中一般会有多个盘片组成,每个盘片包含两个面,每个盘面都对应地有一个读/写磁头。受到硬盘整体体积和生产成本的限制,盘片数量都受到限制,一般都在5片以内。盘片的编号自下向上从0开始,如最下边的盘片有0面和1面,再上一个盘片就编号为2面和3面。

操作系统看这一篇就够了(万字长文)_第7张图片

每个磁道划分若干扇区,扇区的值是 512 字节。**在现代磁盘中,较外部的柱面比较内部的柱面有更多的扇区。**机械臂从一个柱面移动到相邻的柱面大约需要 1ms。而随机移到一个柱面的典型时间为 5ms 至 10ms,具体情况以驱动器为准。一旦磁臂到达正确的磁道上,驱动器必须等待所需的扇区旋转到磁头之下,才开始读写。

操作系统看这一篇就够了(万字长文)_第8张图片

块/簇

  • 概述:块/簇由若干个扇区组成,它们是虚拟出来的概念,每个簇或者块包含2的n次方个扇区。块是操作系统中的针对磁盘的最小存储单位,操作系统和磁盘打交道的最小单位是磁盘块。(操作系统与内存之间进行操作的时候,则是虚拟一个page来作为最小单位

  • 为什么存在磁盘块:由于扇区数目众多,寻址时比较困难,所以就将多个相邻的扇区组成一个块,在操作时对块进行整体操作

固态硬盘(SSD)

固态硬盘的存储介质分为两种,一种是采用闪存(FLASH)为存储介质,一种是采用DRAM为存储介质,通常主流设备采用的是基于闪存的固态硬盘。

相比传统磁盘,固态硬盘的优点有:

  • 读写速度更快,不需要磁头,寻道时间几乎为0
  • 防震抗摔。固态硬盘采用闪存颗粒制作而成,内部不存在任何机械构件,所以发生碰撞的时候数据丢失率很小
  • 低功耗、无噪音、轻便、可拆卸
虚拟内存

当物理内存不够用时,就将硬盘上的一部分临时空间用来充当内存使用,但是这部分虚拟内存只能代替物理内存的存储功能,只能用来存放数据,不能代替物理内存的运行功能。

虚拟内存在硬盘上其实就是为一个硕大无比的文件,文件名为pagefile.sys。

MMU

把程序生成的地址转换为有关字节在 RAM 中的物理地址(把虚拟地址映射到物理地址)。这种映像由 CPU 中的一个称为 存储器管理单元(Memory Management Unit, MMU) 的部件来完成。

4、I/O设备

操作系统看这一篇就够了(万字长文)_第9张图片

I/O设备一般包括两个部分:设备控制器与设备本身。

设备控制器

设备控制器本身是一块芯片或一组芯片,一方面它可以接收操作系统的指令,另一方面,它可以控制物理设备。控制器的目的是给操作系统提供一个更简单的接口,屏蔽物理细节。

设备驱动程序

每种类型的设备控制器都是不同的,所以需要不同的软件进行控制。专门与控制器进行信息交流,发出命令处理指令、接收响应的软件,称为 设备驱动程序(device driver)。每个控制器厂家都应该针对不同的操作系统提供不同的设备驱动程序。

为了使设备驱动程序工作,必须把它安装在操作系统中,这样能够使它在内核态中运行。

将驱动程序装入操作系统有三种方法:

  • 将内核与设备驱动动程序重新连接,然后重启系统。(Unix)
  • 在一个操作系统文件中设置一个入口,通知该文件需要一个设备驱动程序,然后重新启动系统。在重新系统时,操作系统回寻找有关的设备驱动程序并把它装载(Windows)
  • 操作系统在运行时接收新的设备驱动程序并立刻安装,无需重启操作系统。热插拔设备,比如 USB 和 IEEE 1394 都需要动态可装载的设备驱动程序。
操作系统看这一篇就够了(万字长文)_第10张图片
设备寄存器(I/O端口)

每个设备控制器都有少量用于通信的寄存器,每个外设都是通过读写其寄存器来控制的。外设寄存器也称为I/O端口,通常包括:控制寄存器、状态寄存器和数据寄存器三大类。要激活控制器,设备驱动程序会从操作系统获取一条指令,然后翻译成对应的值,并写入设备寄存器中,所有设备寄存器的结合构成了 I/O 端口空间

访问端口的两种方式
  • I/O内存方式。CPU将寄存器看作内存的一部分,寄存器参与内存统一编址,访问寄存器就通过访问一般的内存指令进行,所以,这种CPU没有专门用于设备I/O的指令。
  • I/O端口方式。CPU将外设的寄存器看成一个独立的地址空间,所以访问内存的指令不能用来访问这些寄存器,而要为对外设寄存器的读/写设置专用指令,如IN和OUT指令。但是,用于I/O指令的“地址空间”相对来说是很小的,如x86 CPU的I/O空间就只有64KB(0-0xffff)。
输入输出的三种方式
  • 最简单的方式称为忙等待,用户程序发起一个系统调用,操作系统将其转化为相应驱动程序的程序调用,然后设备驱动程序启动I/O设备,并循环检查该设备,看设备是否完成了工作。当I/O完成工作后,设备驱动程序将数据送到指定的地方并返回,然后操作系统将控制权交给调用者。这种方式的缺点是要一直占据CPU,CPU会一直轮询设备直到操作完成。
操作系统看这一篇就够了(万字长文)_第11张图片
  • 第二种方式是设备驱动程序启动设备并且让该设备在操作完成时发生中断。设备驱动程序在这个时刻返回。操作系统接着在需要时阻塞调用者并安排其他工作进行。当设备驱动程序检测到该设备操作完成时,它发出一个 中断通知操作完成。

    操作系统看这一篇就够了(万字长文)_第12张图片

    如上图所示,这是一个三步的 I/O 过程

    • 第一步,设备驱动程序会通过写入设备寄存器告诉设备控制器应该做什么。然后,设备控制器启动设备。
    • 当控制器完成读取或写入需要传输的字节后,它会在步骤 2 中使用某些总线向中断控制器发送信号。
    • 如果中断控制器准备好了接收中断信号(如果正忙于一个优先级较高的中断,则可能不会接收),那么它就会在 CPU 的一个引脚上面声明。这就是步骤3
    • 在第四步中,中断控制器把该设备的编号放在总线上,这样 CPU 可以读取总线,并且知道哪个设备完成了操作(可能同时有多个设备同时运行)。

    一旦 CPU 决定去实施中断后,程序计数器和 PSW 就会被压入到当前堆栈中并且 CPU 会切换到内核态。设备编号可以作为内存的一个引用,用来寻找该设备中断处理程序的地址。这部分内存称作中断向量(interrupt vector)。一旦中断处理程序(中断设备的设备驱动程序的一部分)开始后,它会移除栈中的程序计数器和 PSW 寄存器,并把它们进行保存,然后查询设备的状态。在中断处理程序全部完成后,它会返回到先前用户程序尚未执行的第一条指令,这个过程如下

    操作系统看这一篇就够了(万字长文)_第13张图片
  • 实现 I/O 的第三种方式是使用特殊的硬件:直接存储器访问(Direct Memory Access, DMA) 芯片。它可以控制内存和某些控制器之间的位流,而无需 CPU 的干预。CPU 会对 DMA 芯片进行设置,说明需要传送的字节数,有关的设备和内存地址以及操作方向。当 DMA 芯片完成后,会造成中断,中断过程就像上面描述的那样。我们会在后面具体讨论中断过程

5、总线

下面是一个大型的x86系统的结构,包含很多总线,高速缓存、内存、PCIe、PCI、SATA、USB和DMI,每条总线都有不同的传输速率和功能,最主要的是PCIe总线。(PCI设备一般为网卡、声卡、显卡等)

操作系统看这一篇就够了(万字长文)_第14张图片

PCIe总线是作为PCI的继承者,其传输能力能达到数十GB/s,直到PCIE发明之前,大多数总线都是并行且共享的。

  • 共享总线架构:多个设备使用相同的一些电线传输数据,这就需要一个决策者决定谁能够使用总线
  • 并行总线架构(PCI):通过多条数据线发送相同的数据字。比如32bit的数据使用32条并行的电线传输。

这样就会出现一个问题,并行的连线在高速传输时会出现严重的干扰,时钟频率越快,干扰越大,所以就出现了串行总线架构。

  • 串行总线架构(PCIe):使用差分信号传输,干扰可以很快被发现和纠正,通信方式由半双工变成全双工。

6、计算机启动过程

主板

在每台计算机上有一块双亲板,也就是母板,母板也就是主板,它是计算机最基本也就是最重要的部件之一。主板一般为矩形电路板,上面安装了组成计算机的主要电路系统,一般有 BIOS 芯片、I/O 控制芯片、键盘和面板控制开关接口、指示灯插接件、扩充插槽、主板及插卡的直流电源供电接插件等元件。

操作系统看这一篇就够了(万字长文)_第15张图片

BIOS

  • 定义:是一组固定在主板ROM芯片上的程序,包括最基本的输入/输出程序

  • 目的:为计算机提供最基本、最直接的硬件控制

  • 功能

    • 自检初始化。开机后BIOS对硬件进行检查,参数满足后才能启动系统
    • 程序服务处理。BIOS通过特定的端口发送或接收外部设备的数据,从而实现软件在硬件上的操作
    • 硬件中断处理。BIOS会告诉CPU硬件设备的中断号,如果我们输入一个硬件命令,它会根据中断号使用相应的硬件来完成命令工作,最后根据中断号跳回原来的状态
  • BIOS中主要存放的程序

    • 自诊断程序(通过读取CMOS RAM中的内容识别硬件配置,并对其进行自检和初始化)
    • CMOS设置程序(引导过程中,通过特殊热键启动,进行设置后,存入CMOS RAM中)
    • 系统自动装载程序(在系统自检成功后,将磁盘相对0道0扇区上的引导程序装入内存使其运行)
    • 主要I/O驱动程序和中断服务(BIOS和硬件直接打交道,需要加载I/O驱动程序)。

CMOS

CMOS在电脑主板上用来保存 BIOS 设置完电脑硬件参数后的数据。

MBR

  • 定义:设备的第一个扇区,也就是读取最前面的512个字节,就叫做”主引导记录”(Master boot record)。

  • 主要功能:

    • 检查硬盘分区表是否完好
    • 在分区表中寻找可引导的活动分区
    • 将活动分区的PBR装入内存
  • 结构:

    • 第1-446字节:调用操作系统的机器码。
    • 第447-510字节:分区表(Partition table),将磁盘分成若干个区
    • 第511-512字节:主引导记录签名(0x55和0xAA)。
  • 分区表

    • 分区表里又分成4项,每项16个字节。一个硬盘最多只能分四个一级分区,又叫做”主分区”。
    • 每个区可以安装不同的操作系统,MBR必须知道将控制权转交给哪个区。
    • 每个主分区的16个字节,由6个部分组成:
      • 第1个字节:如果为0x80,就表示该主分区是激活分区,控制权要转交给这个分区。四个主分区里面只能有一个是激活的。
      • 第2-4个字节:主分区第一个扇区的物理位置(柱面、磁头、扇区号等等)。
      • 第5个字节:主分区类型。
      • 第6-8个字节:主分区最后一个扇区的物理位置。
      • 第9-12字节:该主分区第一个扇区的逻辑地址。
      • 第13-16字节:主分区的扇区总数。
    • 主分区的扇区总数,决定了这个主分区的长度。如果想使用更大的硬盘,只有2个方法:一是提高每个扇区的字节数,二是增加扇区总数。

启动过程

操作系统看这一篇就够了(万字长文)_第16张图片

1、BIOS加电自检

计算机启动时,BIOS开启,首先检查,计算机硬件能否满足运行的基本条件。如果硬件出现问题,主板会发出不同含义的蜂鸣,启动中止。如果没有问题,屏幕就会显示出CPU、内存、硬盘等信息。

2、BIOS转交控制权

BIOS需要有一个外部储存设备的排序,把控制权转交给排在第一位的储存设备,也就是把控制权交给下一阶段的启动程序所在的设备。

3、读取MBR

计算机根据用户指定的引导顺序从软盘、硬盘或是可移动设备中读取启动设备的主引导记录(MBR),并放入内存中。

该设备的第一个扇区,最前面的512个字节就叫做”主引导记录”(Master boot record,缩写为MBR)。如果这512个字节的最后两个字节是0x55和0xAA,表明这个设备可以用于启动;如果不是,表明设备不能用于启动,控制权于是被转交给”启动顺序”中的下一个设备。

MBR引导程序扫描所有分区表,找出活动分区,加载并启动保存在活动分区PBR中的引导程序

4、计算机转交控制权

计算机的控制权转交给硬盘的某个分区,这里有三种情况

  • 情况A:分区引导记录

    计算机读取激活分区的第一个扇区,叫做”分区引导记录”(PBR)。

    “分区引导记录”告诉计算机,操作系统在这个分区里的位置。然后,计算机就会加载操作系统了。

  • 情况B:扩展分区和逻辑分区

    很少通过这种方式启动操作系统。如果操作系统确实安装在扩展分区,一般采用下一种方式启动。

  • 情况C:启动管理器

    计算机读取”主引导记录”前面446字节的机器码之后,不再把控制权转交给某一个分区,而是运行事先安装的”启动管理器”(boot loader),由用户选择启动哪一个操作系统。

5、启动操作系统

控制权转交给操作系统后,操作系统的内核首先被载入内存。然后,产init进程,加载系统的各个模块,直到跳出登录界面,等待用户输入用户名和密码。

至此,全部启动过程完成。

三、操作系统结构

1、单体系统

到目前为止,在大多数系统中,整个系统在内核态以单一程序的方式运行整个操作系统是以程序集合来编写的,链接在一块形成一个大的二进制可执行程序。

  • 优点:在单体系统中,调用任何一个所需要的程序都非常高效
  • 缺点:
    • 上千个不受限制的彼此调用往往非常臃肿和笨拙
    • 单体系统必然存在单体问题,只要系统发生故障,任何系统和应用程序将不可用。

在单体系统中构造实际目标程序时,会首先编译所有单个过程(或包含这些过程的文件),然后使用系统链接器将它们全部绑定到一个可执行文件中

除了在计算机初启动时所装载的核心操作系统外,许多操作系统还支持额外的扩展。比如 I/O 设备驱动和文件系统。这些部件可以按需装载。在 UNIX 中把它们叫做 共享库(shared library),在 Windows 中则被称为 动态链接库(Dynamic Link Library,DLL)。他们的扩展名为 .dll,在 C:\Windows\system32 目录下存在 1000 多个 DLL 文件。

2、库文件

​ 可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。

1、静态链接库

采用静态链接库的方式,静态库在程序的链接阶段被复制到了程序中,和程序运行的时候没有关系

2、动态链接库

概念:动态库(DLL文件)在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用

优点:系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存。

3、区别

  • 概念上的区别

  • 静态链接库中不能再包含其他库(动态链接库或者静态库)

    动态链接库中还可以再包含其他库(动态或静态链接库)

3、分层系统

概念:分层系统使用层来分隔不同的功能单元,每一层为上一层提供服务,调用下一层的服务

操作系统看这一篇就够了(万字长文)_第17张图片

把单体系统进一步通用化,就变为了一个层次式结构的操作系统,它的上层软件都是在下层软件的基础之上构建的。该系统分为六层,如下所示

操作系统看这一篇就够了(万字长文)_第18张图片

4、微内核

  • 目的:为了提高操作系统的可靠性,尽可能减少内核态中功能,否则一旦内核态中出错误会拖累整个系统。

  • 概念:将操作系统划分成小的、层级之间能够更好定义的模块,只有一个模块 — 微内核 — 运行在内核态,其余模块可以作为普通用户进程运行。

  • 好处:如果某个模块出错,虽然会使模块崩溃,但不会使整个系统死机

  • 内核思想:**机制与策略分离。**比如系统调度,一个比较简单的调度算法是,对每个进程赋予一个优先级(策略),内核执行具有最高优先级的进程(机制)。策略就可以在用户态的进程中完成,实现策略和机制的分离,使内核更小。

MINIX 3 是微内核的代表作,它的具体结构如下

操作系统看这一篇就够了(万字长文)_第19张图片

最底层的设备驱动器不能物理地访问I/O端口,也不能发出I/O命令,为了能对I/O设备编程,驱动器构建一个结构,指明哪个参数值写到哪个I/O端口,并声称一个内核调用,这样就完成了一次调用过程。

服务器层完成操作系统的多数任务,由一个或多个文件服务器管理着文件系统。进程管理器创建、销毁和管理进程

服务器中有一个特殊的服务器称为 再生服务器(reincarnation server),它的任务就是检查服务器和驱动程序的功能是否正确,一旦检查出来错误,它就会补上去,无需用户干预。这种方式使得系统具有可恢复性,并具有较高的可靠性。

四、操作系统的类型

1、大型机操作系统

一个大型计算机有 1000 个磁盘和数百万 G 字节的容量是很正常的,这些大型操作系统可在大型公司的数据中心找到。大型机也常用在在高端 Web 服务器、大型电子商务服务站点上。

2、服务器操作系统

运行在服务器上,服务器可以是大型个人计算机、工作站甚至是大型机。它们通过网络为若干用户服务,并且允许用户共享硬件和软件资源。服务器可提供打印服务、文件服务或 Web 服务。Internet 服务商运行着许多台服务器机器,为用户提供支持,使 Web 站点保存 Web 页面并处理进来的请求。

3、多处理器操作系统

为了获得大型计算能力,一种较普遍的方式是将多个 CPU(处理器) 连接到一个系统中。依据它们连接方式和共享方式的不同,这些系统称为并行计算机,多计算机或多处理器。他们需要专门的操作系统。

多处理器和多核

  • 多处理器:每一个处理器都要有独立的电路支持,有自己的cache,处理器之间通过电路板上的总线进行通信。假如运行一个多线程的程序,那么每一个线程就要运行在一个独立的cpu上,线程间的所有协作都要通过总线,而且共享的数据有可能在好几个cache里同时存在,这样的话会出现总线开销过大,存储空间的浪费与共享数据的一致性问题。

  • 多核:只需要一套芯片组,一套存储,多核之间通过芯片内部总线进行通信,共享使用内存。如果运行一个多线程的程序,线程间的通信将更快,对板上空间的占用也比较小。

  • 多处理器的优点:假如同时运行多个大程序,每一个程序都有很多线程,还几乎用满cache,程序分时使用CPU,当程序间切换的时候,指令和数据的替换会有非常大的开销,这个时候使用多处理器就更加合适。

4、掌上计算机操作系统

比如平板电脑、智能手机等掌上计算机系统。掌上计算机或者 PDA(Personal Digital Assistant),个人数字助理 是一种可以握在手中操作的小型计算机。这部分市场已经被谷歌的 Android 系统和苹果的 IOS主导。

5、嵌入式操作系统

嵌入式操作系统用来控制设备的计算机中运行,这种设备不是一般意义上的计算机,并且不允许用户安装软件。

典型的例子有微波炉、汽车、DVD 刻录机、移动电话以及 MP3 播放器一类的设备。所有的软件都运行在 ROM 中,这意味着应用程序之间不存在保护,从而获得某种简化。主要的嵌入式系统有 Linux、QNX 和 VxWorks

6、传感器节点操作系统

有许多用途需要配置微小传感器节点网络。这些节点是一种可以彼此通信并且使用无线通信基站的微型计算机。每个传感器节点是一个配有 CPU、RAM、ROM 以及一个或多个环境传感器的实实在在的计算机。节点上运行一个小型操作系统,通常这个操作系统是事件驱动的,可以响应外部事件。

这类传感器网络可以用于建筑物周边保护、国土边界保卫、森林火灾探测、气象预测用的温度和降水测量等。

7、实时操作系统

实时操作系统的特征是将时间作为关键参数。

  • 硬实时系统:某个动作必须要在规定的时刻发生。常见于工业控制、民用航空、军事以及类似应用
  • 软实时系统:虽然不希望偶尔违反最终时限,但仍可以接受,并不会引起任何永久性损害。数字音频或多媒体系统就是这类系统。智能手机也是软实时系统。

8、智能卡操作系统

智能卡是一种包含一块 CPU 芯片的信用卡。它有非常严格的运行能耗和存储空间的限制。

有些卡具有单项功能,如电子支付;有些智能卡是面向 Java 的。这意味着在智能卡的 ROM 中有一个 Java 虚拟机解释器。

五、操作系统概念

1、进程

  • 定义:进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。

  • 引入进程的原因:清晰地刻画动态系统的内在规律,有效管理和调度运行的程序。

  • 组成:进程控制块、程序段、数据段

地址空间

每一个进程都有它自己的地址空间,在这个地址空间中,进程可以进行读写操作。

一般情况下,地址空间包括文本区、数据区和堆栈。文本区存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。

一个进程可拥有的最大地址空间小于主存。在这种情况下,即使进程用完其地址空间,内存也会有足够的内存运行该进程。

操作系统看这一篇就够了(万字长文)_第20张图片

UNIX 中的进程将内存划分成上述地址空间的三个部分,如上图所示

数据向上增长而堆栈向下增长,夹在中间的是空闲区,也就是未分配的区域,堆栈在需要时自动的挤压空闲区域,不过数据段的扩展是显示地通过系统调用 brk 进行的,在数据段扩充后,该系统调用指向一个新地址。

进程控制块(PCB)

进程控制块(PCB)是系统为了管理进程设置的一个专门的数据结构。

操作系统用它来记录进程的外部特征,描述进程的运动变化过程。同时,系统可以利用PCB来控制和管理进程,所以说,PCB是系统感知进程存在的唯一标志。

PCB通常包括程序计数器、进程状态、CPU暂存器(比如累加器、堆栈指针)…等内容

上下文切换

上下文切换,是指一个进程或线程切换到另一个进程或线程,包括保存当前任务的运行环境,恢复将要运行任务的运行环境。

进程上下文通常用PCB表示,它包括进程状态,CPU寄存器的值等内容。当进程上下文切换时,CPU会停止当前运行的程序,并将当前程序的一些信息保存在PCB中,以便之后继续运行程序。

在三种状态下可能产生上下文切换:

  • 中断处理
  • 多任务处理
  • 用户态切换

上下文切换的消耗很大,可能是操作系统中时间消耗最大的操作。

进程与线程

  • 一个程序至少一个进程,一个进程至少一个线程。
  • 同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。
  • 通常都是把进程作为分配资源的基本单位,而把线程作为处理器独立运行和调度的基本单位.
  • 由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。
  • 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
操作系统看这一篇就够了(万字长文)_第21张图片

2、文件系统

定义:是操作系统中统一管理信息资源的一种软件

文件系统包含文件管理程序(文件与目录的集合)和所管理的全部文件 , 是用户与外存的接口 , 系统软件为用户提供统一方法,访问存储在物理介质上的信息。

在读写文件之前,首先需要打开文件,检查其访问权限。若权限许可,系统将返回一个小整数,称作文件描述符(file descriptor),供后续操作使用。若禁止访问,系统则返回一个错误码。

特殊文件

在 UNIX 中,有一个重要的概念是特殊文件(special file)。提供特殊文件是为了使 I/O 设备看起来像文件一般。这样,就像使用系统调用读写文件一样,I/O 设备也可以通过同样的系统调用进行读写。

特殊文件有两种,一种是块特殊文件(block special file)字符特殊文件(character special file)

块特殊文件指那些由可随机存取的块组成的设备,如磁盘等。比如打开一个块特殊文件,然后读取第4块,程序可以直接访问设备的第4块而不必考虑存放在该文件的文件系统结构。

类似的,字符特殊文件用于打印机、调制解调起和其他接受或输出字符流的设备。按照惯例,特殊文件保存在 /dev 目录中。例如,/devv/lp 是打印机。

3、保护

计算机中含有大量的信息,用户希望能够对这些信息中有用而且重要的信息加以保护,这些信息包括电子邮件、商业计划等,管理这些信息的安全性完全依靠操作系统来保证。

比如 UNIX 操作系统,对每个文件赋予一个 9 位二进制保护代码。保护代码有三个位子段,一个用于所有者,一个用于与所有者同组(用户被系统管理员划分成组)的其他成员,一个用于其他人。每个字段中有一位用于读访问,一位用于写访问,一位用于执行访问。这些位就是著名的 rwx位

例如,保护代码 rwxr-x--x 的含义是所有者可以读、写或执行该文件,其他的组成员可以读或执行(但不能写)此文件、而其他人可以执行(但不能读和写)该文件。

4、系统调用(UNIX)

一个进程在用户态下运行用户程序,如果想要把控制权交给操作系统控制,那么必须

  • 执行一个异常指令或者系统调用指令
  • 操作系统紧接着进行参数检查找出所需要的调用进程
  • 执行系统调用,把控制权移交给系统调用下面的指令

系统调用就像是执行了一个特殊的过程调用,但是只有系统调用能够进入内核态而过程调用则不能进入内核态

进程管理的系统调用

常用的系统调用如下表所示

调用 说明
pid = fork() 创建与父进程相同的子进程
pid = waitpid(pid, &statloc,options) 等待一个子进程终止
s = execve(name,argv,environp) 替换一个进程的核心映像
exit(status) 终止进程执行并返回状态
fork()
  • 作用:在 UNIX 中,fork 是唯一可以在 POSIX 中创建进程的途径,它创建一个原有进程的副本,包括所有的文件描述符、寄存器等内容。

  • 进程关系:在 fork 之后,原有进程以及副本就分开了。在 fork 过程中,所有的变量都有相同的值,虽然父进程的数据通过复制给子进程,但是后续对其中任何一个进程的修改不会影响到另外一个。

  • 返回值:fork 调用会返回一个值,在子进程中该值为 0 ,并且在父进程中等于子进程的 进程标识符(Process IDentified,PID)。使用返回的 PID,就可以看出来哪个是父进程和子进程。

  • 进程结束:有时为了等待子进程完成,父进程需要执行 waitpid 系统调用,父进程会等待直至子进程终止(若有多个子进程的话,则直至任何一个子进程终止)。waitpid 可以等待一个特定的子进程,或者通过将第一个参数设为 -1 的方式,等待任何一个比较老的子进程。

execve(name,argv,env)
  • 作用:引起整个核心映像被一个文件所替代
  • 三个参数:将要执行的文件名称,一个指向变量数组的指针,以及一个指向环境数组的指针。

文件管理的系统调用

调用 说明
fd = open(file, how,…) 打开一个文件使用读、写
s = close(fd) 关闭一个打开的文件
n = read(fd,buffer,nbytes) 把数据从一个文件读到缓冲区中
n = write(fd,buffer,nbytes) 把数据从缓冲区写到一个文件中
position = iseek(fd,offset,whence) 移动文件指针
s = stat(name,&buf) 取得文件状态信息

许多系统调用都与文件系统有关,要读写一个文件,必须先将其打开。这个系统调用通过绝对路径名或指向工作目录的相对路径名指定要打开文件的名称,而代码 O_RDONLYO_WRONLYO_RDWR 的含义分别是只读、只写或者两者都可以,为了创建一个新文件,使用 O_CREATE 参数。然后可使用返回的文件描述符进行读写操作。接着,可以使用 close 关闭文件,这个调用使得文件描述符在后续的 open 中被再次使用。

iseek(fd,offset,whence)
  • 作用:调用可以改变该位置指针的值,随机访问一个文件的任意部分
  • 三个参数:第一个是文件描述符,第二个是偏移量,第三个是说明文件相对于哪个位置(头或尾)
  • 返回值:在修改了指针之后,Iseek 所返回的值是文件中的绝对位置。
stat(name,&buf)
  • 作用:查看文件的类型、大小、修改时间等信息
  • 两个参数:第一个参数指定了被检查的文件;第二个参数是一个指针,该指针指向存放这些信息的结构。

目录管理的系统调用

调用 说明
s = mkdir(nname,mode) 创建一个新目录
s = rmdir(name) 删去一个空目录
s = link(name1,name2) 创建一个新目录项 name2,并指向 name1
s = unlink(name) 删去一个目录项
s = mount(special,name,flag) 安装一个文件系统
s = umount(special) 卸载一个文件系统

其他系统调用

调用 说明
s = chdir(dirname) 改变工作目录
s = chmod(name,mode) 修改一个文件的保护位
s = kill(pid, signal) 发送信号给进程
seconds = time(&seconds) 获取从 1970 年1月1日至今的时间

参考文章:

当初我要是这么学习操作系统就好了(附带思维导图)

进程、线程、服务和任务的区别以及多线程与超线程的概念 - Lxk- - 博客园

缓存命中_Java_zhutaorun的博客-CSDN博客

硬盘基本知识(磁头、磁道、扇区、柱面) - js王 - 博客园

PCI与PCIe学习一——硬件篇_嵌入式_咸鱼弟的博客-CSDN博客

计算机的启动过程(详细)_网络_恩来贺的博客-CSDN博客

你可能感兴趣的:(操作系统看这一篇就够了(万字长文))