操作系统(一)
操作系统概述
什么是操作系统?
没有公认定义,可以理解为起协助作用的控制程序,或者是介于软硬件之间的资源管理器。
操作系统软件组成
- Shell 命令行接口
- 通过键盘操纵
- 方便用户进行命令输入
- GUI 图形用户接口
- WIMP
视窗(windows)、t图标(icon)、选单(menu)、指标(pointer) - 直接操作、所见即所得
- WIMP
- Kernel 操作系统内核
- 执行各种资源管理等功能
操作系统内核
- 并发:计算机系统中同时存在多个运行的程序,需要 OS 管理和调度
- 共享:“同时”访问(宏观),互斥共享(微观:对资源进行隔离保护)
- 虚拟:高频率交替(多道程序设计技术),使用户感觉在专用系统
- 异步:程序执行时间难于预测,运行环境相同时,OS 需要保证输出结果相同
系统类型
- UNIX(开放):UNIX BSD、Mac OS等
- Linux(与 UNIX 同一类,API 兼容或类似,开放程度更完整):Ubuntu、安卓等
- Windows(专用和封闭,图形用户接口,易用)
操作系统主要功能:硬件抽象和协调管理
操作系统的演变
- 单用户系统
- 批处理系统
- 多程序系统
- 分时
- 个人计算机:每个用户一个系统
- 分布式计算:每个用户多个系统
操作系统结构
- 简单结构:无模块划分,主要汇编,不可移植
- 分层结构:
- 将操作系统分为多层(levels)
- 每层建立在底层之上
- 最底层(layer 0)是硬件
- 最高层(layer N)是用户界面
- 每一层仅使用更低一层的功能(操作)和服务
- 将操作系统分为多层(levels)
- 微内核结构(Microkernel):
- 尽可能把内核功能移到用户空间
- 用户模块间的通信使用消息传递
- 好处:灵活、安全
- 缺点:性能
- 外核结构(Exokernel):
- 内核少放东西,资源管理由应用态代码完成,一个系统支起不同的操作系统服务
- 让内核分配机器的物理资源给多个应用程序,并让每个程序决定如何处理这些资源
- 程序能链接到操作系统库(libOS)实现了操作系统抽象
- 保护和控制隔离
- VMM(虚拟机管理器,非操作系统结构):
- 负责和硬件接触(隔离资源),操作系统负责资源管理
- 虚拟机管理器将单独的机器接口转换成很多的虚拟机,每个虚拟机都是一个原始计算机系统的有效副本,并能完成所有的处理器指令
对于主流操作系统的结构分析
Windows
Windows 属于比较接近微内核的混合内核结构,这样的结构有一个特点,那就是驱动是单独分发的,并不会和 Windows 的微内核混合在一起。因此,其驱动配置比较简单,无需改动 Windows 内核代码。Linux
Linux 是一个宏内核的结构,在保留了微内核结构优点的基础上进行了优化。Linux 的驱动和内核是整合在一起的,要适配某种硬件,得把驱动都整合进 Linux 内核。它是模块化的、多线程的以及内核本身可调度的操作系统。Linux 仅仅是一个单块内核,单个内核负责管理 CPU、内存、进程间通信、设备驱动程序、文件系统和系统服务器调用。Mac OS
Mac OS 的内核(XNU)结合了微内核(Mach)和单片内核的(BSD)的特性。根据苹果公司的 Github 页面,XNU 是将卡耐基梅隆大学开发的 Mach 内核和 FreeBSD 组件整合而成的混合内核,加上用于编写驱动程序的 C++ API。代码的 BSD 子系统部分在微内核系统中,通常实现为用户空间的服务。Mach 部分负责底层工作,例如多任务、内存保护、虚拟内存管理、内核调试支持和控制台 I/O。
启动、中断、异常和系统调用
BIOS启动固件
基本功能:
- 基本输入输出的程序
- 系统设置信息
- 开机后自检程序
- 系统自启程序等
BIOS 系统调用:
- BIOS 以中断调用的方式提供了基本的 I/O 功能
- INT 10h:字符显示
- INT 13h:磁盘扇区读写
- INT 15h:检测内存大小
- INT 16h:键盘输入
- 只能在 x86 的实模式下访问
系统启动流程
- CPU 初始化
- CPU 加电稳定后从 0XFFFF0 读第一条指令
- CS:IP = 0xf000:fff0
- 第一条指令是跳转指令
- CPU 初始状态为16位实模式
- CS:IP 是16位寄存器
- 指令指针 PC = 16 * CS + IP
- 最大地址空间是 1MB
- CPU 加电稳定后从 0XFFFF0 读第一条指令
- BIOS 初始化
- 硬件自检 POST
- 检测系统中内存和显卡等关键部件的存在和工作状态
- 查找并执行显卡等接口卡 BIOS ,进行设备初始化
- 执行系统 BIOS ,进行系统检测,检测和配置系统中安装的即插即用设备
- 更新 CMOS 中的扩展系统配置数据 ESCD
- 按指定启动顺序从软盘、硬盘或光驱启动
- 主引导记录 MBR 格式
- 启动代码:446字节
- 检查分区表正确性
- 加载并跳转到磁盘上的引导程序
- 硬盘分区表:64字节
- 描述分区状态和位置
- 每个分区描述信息占据16字节
- 结束标志字:2字节 (55AA)
- 主引导记录的有效标志
- 启动代码:446字节
- 分区引导扇区格式
- 跳转指令:跳转到启动代码
- 与平台相关代码
- 文件卷头:文件系统描述信息
- 启动代码:跳转到加载程序
- 结束标志:55AA
- 跳转指令:跳转到启动代码
- 加载程序(bootloader)
系统启动规范
- BIOS
- 固化到计算机主板上的程序
- 包括系统设置、自检程序和系统自启动程序
- BIOS-MBR、BIOS-GPT、PXE
- UEFI
- 接口标准
- 在所有平台上一致的操作系统启动服务
中断、异常和系统调用
- 系统调用 (system call)
- 应用程序主动向操作系统发出的服务请求
- 异常
- 非法指令或者其他原因导致当前指令执行失败 (如:内存出错)后的处理请求
- 中断
- 来自硬件设备的处理请求
- 区别:
- 源头
- 中断:外设
- 异常:应用程序意想不到的行为
- 系统调用:应用程序请求操作提供服务
- 响应方式
- 中断:异步
- 异常:同步
- 系统调用:同步或异步
- 处理机制
- 中断:持续,对用户应用程序是透明的
- 异常:杀死或者重新执行意想不到的应用程序指令
- 系统调用:等待和持续
- 源头
中断处理机制
- 硬件处理
- 在 CPU 初始化时设置中断使能的标志
- 依据内部或外部事件设置中断标志
- 依据中断向量调用相应中断的服务例程
- 在 CPU 初始化时设置中断使能的标志
- 软件
- 现场保存(编译器)
- 中断服务处理(服务例程)
- 清除中断标记(服务例程)
- 现场恢复(编译器)
- 中断嵌套
- 硬件中断服务例程可被打断
- 不同硬件中断源可能硬件中断处理时出现
- 硬件中断服务例程中需要临时禁止中断请求
- 中断请求会保持到 CPU 做出响应
- 异常处理例程可被打断
- 异常服务例程执行时可能出现硬件中断
- 异常服务例程可嵌套
- 异常服务例程可能出现缺页
- 硬件中断服务例程可被打断
系统调用的外界使用
- 操作系统服务的编程接口
- 通常由高级语言编写 (C 或者 C++)
- 程序访问通常是通过高层次的 API 接口而不是直接进行系统调用
- 三种最常用的应用程序编程接口 (API)
- Win32 API 用于 Windows
- POSIX API 用于 POSIX-based systems (包括 UNIX, LINUX, Mac OS X的所有版本)
- Java API 用于 JAVA 虚拟机 (JVM)
系统调用的内部实现
- 每个系统调用对应一个系统调用号
- 系统调用接口根据系统调用号来维护表的索引
- 系统调用接口调用内核态中的系统调用功能实现,并返回系统调用的状态和结果
- 用户不需要知道系统调用的实现
- 需要设置调用参数和获取返回结果
- 操作系统接口的细节大部分都隐藏在应用编程接口后
- 通过运行程序支持的库来管理
函数调用和系统调用的不同处
- 系统调用
- INT 和 IRET 指令用于系统调用
- 系统调用时,堆栈切换和特权级的转换
- INT 和 IRET 指令用于系统调用
- 函数调用
- CALL 和 RET 用于常规调用
- 常规调用时没有堆栈切换
- CALL 和 RET 用于常规调用
中断、异常和系统调用的开销
系统调用比函数调用更安全,但是系统调用的开销超过函数调用。
中断、异常和系统调用具体开销:
- 引导机制
- 建立内核堆栈
- 验证参数
- 内核态映射到用户态的地址空间
- 更新页面映射权限
- 内核态独立地址空间
- TLB
内存层次
操作系统的内存管理
操作系统的内存管理方式
- 操作系统中采用的内存管理方式
- 重定位 ( relocation )
- 分段 ( segmentation )
- 分页 ( paging )
- 虚拟存储 ( virtual memory )
- 目前多数系统(如 Linux )采用按需页式虚拟存储
- 实现高度依赖硬件
- 与计算机存储架构紧耦合
- MMU(内存管理单元):处理 CPU 存储访问请求的硬件