操作系统
基本信息介绍
操作系统信息
- 在经典的五级结构划分中,计算机组成结构包含数字逻辑层、微体系结构层、指令集架构层、操作系统层、应用程序层。其中前三层属于"硬件层",最后一层属于"软件层"。操作系统的地位就是硬件和软件之间的媒介。扮演资源分配器和控制程序的角色。
计算机系统的四个组成部分
- 硬件(Hardware):提供基本的计算资源
- CPU、内存、I/O设备等
- 操作系统(Operating System):控制和协调硬件在用户之间的使用
- 资源分配器:管理所有资源,决定冲突请求的处理以实现高效和公平的资源共享
- 控制程序:控制程序执行以防止错误和系统的不当使用
- 应用程序(Application Programs):使用系统资源解决计算问题
- 如文字处理器、编译器、Web浏览器等
- 用户(Users):
- 人、机器、其他计算机等
操作系统定义与视角
用户视角 vs 系统视角
- 用户视角:
- 用户需要便利性和易用性
- 不太关心资源利用率
- 共享计算机(如主机)必须让所有用户满意
- 手持设备资源受限,优化可用性和电池寿命
- 系统视角:
- 操作系统是资源分配器
- 操作系统是控制程序
操作系统定义
- 近似定义:“当你订购操作系统时,供应商提供的所有东西”
- 没有普遍接受的定义
- 供应商提供的内容可能差异很大
- 内核(Kernel):“始终在计算机上运行的一个程序”
- 其他都是系统程序或应用程序
- 操作系统在不同上下文中可能有不同含义
计算机系统组成
硬件组件
基本结构
- CPU和设备控制器通过总线连接共享内存
- CPU和设备并发执行,竞争内存周期
设备控制器
- 每个设备控制器负责特定类型的设备
- 磁盘控制器、USB控制器等
- 每个设备控制器都有本地缓冲区
- I/O过程:在设备和控制器本地缓冲区之间进行
- CPU在主内存和控制器缓冲区之间移动数据
- I/O设备和CPU可以并发执行
直接内存访问(DMA)
- 用途:用于能够以接近内存速度传输信息的高速I/O设备
- 如以太网、硬盘、CD-ROM等
- 工作流程:
- 设备驱动程序向控制器发送I/O描述符
- I/O描述符包含:操作类型、内存地址等
- 控制器在其本地缓冲区和主内存之间传输数据块,无需CPU干预
- 整个I/O请求完成时只产生一个中断
中断与陷阱
中断与陷阱讲解
中断(Interrupt)
- 定义:中断是由外部硬件设备产生的异步事件,用来通知CPU某个事件已经发生
- 特点:
- 异步发生:不可预知的时间点
- 由外部硬件触发(如键盘输入、鼠标点击、网络数据到达等)
- CPU可以选择性地响应或屏蔽某些中断
- 类型:
- 硬件中断:由硬件设备产生(如定时器中断、I/O完成中断)
- 软件中断:由软件指令产生(如系统调用)
- 处理流程:
- 硬件检测到中断信号
- CPU完成当前指令执行
- 保存当前程序状态(寄存器、程序计数器等)
- 跳转到中断服务程序(ISR)
- 执行中断处理
- 恢复被中断程序的状态
- 继续执行被中断的程序
陷阱(Trap)
- 定义:陷阱是由正在执行的程序内部产生的同步事件
- 特点:
- 同步发生:在特定指令执行时产生
- 由当前执行的程序触发
- 通常用于系统调用和异常处理
- 类型:
- 系统调用陷阱:用户程序请求操作系统服务
- 异常陷阱:程序执行错误(如除零错误、非法内存访问等)
- 调试陷阱:用于程序调试(如断点)
- 处理流程:
- 程序执行特定指令(如系统调用指令)
- CPU立即响应陷阱
- 切换到内核模式
- 跳转到相应的陷阱处理程序
- 执行系统服务或异常处理
- 返回用户模式(如果适用)
- 继续执行程序
中断与陷阱的区别
- 触发源
- 中断:外部硬件设备
- 陷阱:程序内部指令
- 时机
- 中断:异步,不可预测
- 陷阱:同步,可预测
- 用途
- 中断:处理外部事件,提高系统响应性
- 陷阱:实现系统调用,处理程序异常
- 可屏蔽性
- 中断:部分可屏蔽
- 陷阱:通常不可屏蔽
重要性
- 提高系统效率:避免CPU空等,实现并发处理
- 实现系统调用:用户程序与内核通信的桥梁
- 错误处理:及时处理程序运行时错误
- 实时响应:确保系统能够及时响应外部事件
操作系统对中断的处理
中断处理机制
- 中断向量表(Interrupt Vector Table)
- 存储中断服务程序入口地址的表格
- 每个中断类型对应一个终端号和处理程序地址
- 通常位于内存的固定位置
- 中断优先级
- 可屏蔽中断(Maskable Interrupt):可以被CPU忽略或延迟处理
- 不可屏蔽中断(Non-Maskable Interrupt, NMI):必须立即处理的紧急中断
- 优先级排序:高优先级中断可以打断低优先级中断的处理
中断处理步骤
- 中断识别
- 硬件产生中断信号
- CUPU在每个指令周期结束时检查中断请求
- 确定中断源和中断类型】
- 现场保护
- 自动保存:CPU自动保存程序状态字
- 手动保存:中断服务程序保存其他寄存器内容
- 保存到内核栈或进程控制块
- 中断分发
- 根据中断号查找中断向量表
- 跳转到对应的中断服务程序(ISR)
- 切换到内核模式(如果尚未切换)
- 中断处理
- 执行具体的中断服务代码
- 处理硬件设备的请求
- 现场恢复
- 恢复之前保存的寄存器内容
- 恢复程序状态字和程序计数器
- 返回被中断的程序继续执行
中断处理策略
-
立即处理(Immediate Processing)
- 中断发生时立即处理
- 适用于紧急和高优先级中断
- 可能影响系统响应时间
-
延迟处理(Deferred Processing)
- 将中断处理分为上半部和下半部
- 上半部:快速处理紧急部分,清除中断源
- 下半部:延后处理耗时的非紧急部分
- Linux中的软中断(softirq)和工作队列(workqueue)
-
中断合并(Interrupt Coalescing)
- 将多个相同类型的中断合并处理
- 减少中断处理开销
- 提高系统吞吐量
中断控制器
-
可编程中断控制器(PIC)
- 管理多个中断源
- 设置中断优先级
- 屏蔽特定中断
-
高级可编程中断控制器(APIC)
- 支持多处理器系统
- 提供更灵活的中断路由
- 支持中断重定向和负载均衡
现代操作系统的优化
-
中断线程化
- 将中断处理程序作为内核线程运行
- 提高系统的实时性和可预测性
- 便于调试和性能分析
-
中断亲和性(Interrupt Affinity)
- 将特定中断绑定到特定CPU核心
- 提高缓存利用率和性能
- 减少处理器间通信开销
-
动态中断分配
- 根据系统负载动态调整中断处理
- 实现负载均衡
- 适应不同的工作负载模式
I/O
I/O基本介绍
从系统调用到设备的I/O过程
- 系统调用访问:程序使用系统调用访问系统资源
- 如文件、网络等
- 设备访问转换:操作系统将其转换为设备访问并发出I/O请求
- I/O请求传输:I/O请求发送到设备驱动程序,然后到控制器
- 如读取磁盘块、发送/接收数据包等
- 等待处理:
- 同步I/O:OS让程序等待
- 异步I/O:OS不等待直接返回给程序
- 进程切换:当请求者等待时,OS可能切换到另一个程序
- I/O完成:I/O完成后控制器中断OS
- 处理结果:
- 同步I/O:OS处理I/O然后唤醒程序
- 异步I/O:OS发送信号给程序
中断驱动的I/O循环
- 操作系统通常是中断驱动的
- 中断传输控制到中断服务程序
- 中断向量:包含所有服务程序地址的表格
- 在服务另一个中断时,传入的中断被禁用以防止中断丢失
- 中断处理程序必须保存(被中断的)执行状态
中断处理详细流程
- 中断识别:
- 硬件产生中断信号
- CPU在每个指令周期结束时检查中断请求
- 确定中断源和中断类型
- 现场保护:
- 操作系统保存CPU的执行状态
- 保存寄存器和程序计数器(PC)
- 中断分发:
- OS确定哪个设备造成了中断
- 轮询(Polling)或向量中断系统
- 中断处理:
- OS通过调用设备驱动程序处理中断
- 现场恢复:
- OS将CPU执行恢复到保存的状态
存储结构
存储层次结构
主存储器
- 主内存:CPU能够直接访问的唯一大容量存储
- 随机访问,通常是易失性的
- 辅助存储:大容量非易失性存储
- 磁盘是最常见的辅助存储设备(HDD)
- 由覆盖磁性记录材料的刚性金属或玻璃盘片组成
- 磁盘表面逻辑上分为磁道和扇区
- 磁盘控制器决定OS和设备之间的交互
存储系统层次结构
存储系统可以按层次组织,考虑以下因素:
- 速度(Speed)
- 成本(Cost)
- 易失性(Volatility)
存储性能层次(从快到慢):
- CPU寄存器
- CPU缓存(L1/L2/L3)
- 主内存(RAM)
- 辅助存储(SSD/HDD)
- 光学存储/磁带
缓存
缓存基本概念
缓存原理
- 缓存:将信息复制到更快存储系统中
- 主内存可以看作是辅助存储的缓存
- CPU缓存是主内存的缓存
- 缓存是在多个级别执行的重要原理
- 硬件、操作系统、用户程序等
缓存工作机制
- 数据复制:使用中的数据从较慢存储临时复制到较快存储
- 缓存检查:首先检查较快存储(缓存)以确定数据是否存在
- 缓存命中:如果在缓存中,直接从缓存使用数据(快速)
- 缓存未命中:如果不在缓存中,先将数据复制到缓存然后使用
- 缓存特点:缓存通常比被缓存的存储小
缓存管理
- 缓存管理是重要的设计问题
- 缓存大小
- 替换策略
- 多任务环境必须小心使用最新值,无论它存储在存储层次的哪里
- 多处理器环境必须在硬件中提供缓存一致性,确保所有CPU在其缓存中都有最新值
虚拟缓存 vs 物理缓存
- 虚拟缓存:使用虚拟地址进行缓存
- 物理缓存:使用物理地址进行缓存
- 缓存一致性:多处理器必须保证缓存一致性
计算机系统架构
系统分类
根据通用处理器数量分类:
- 单处理器系统
- 多处理器系统
单处理器系统
- 大多数老系统只有一个通用处理器
- 如智能手机、PC、服务器、主机
- 大多数系统也有专用处理器
多处理器系统
基本特征
- 别名:并行系统、紧耦合系统
- 优势:
- 增加吞吐量
- 规模经济
- 增加可靠性:优雅降级或容错
多处理器类型
- 非对称多处理(Asymmetric Multiprocessing)
- 对称多处理(SMP, Symmetric Multiprocessing)
多核设计
多核 vs 超线程
- 多核:单个芯片中多个CPU核心
- 超线程:两个程序可以同时使用一个执行单元(在一个核心内)
- 性能依赖:操作系统、编译器、应用程序
NUMA架构
- 非统一内存访问系统(Non-Uniform Memory Access)
- 本地内存访问快速,可扩展性好
集群系统
- 多个系统通过高速网络协同工作
- 通常通过**存储区域网络(SAN)**共享存储
- 高可用性服务,可以在故障中生存
- 非对称集群:一台机器处于热备用模式
- 对称集群:多个节点运行应用程序,相互监控
- 高性能计算(HPC):应用程序必须编写以使用并行化
分布式系统
- 独立系统集合,可能是异构的,通过网络互连
- 网络OS允许系统交换消息
- 分布式系统创建单一系统的错觉
特殊用途系统
实时嵌入式系统
- 最普遍的计算机形式
- 变化很大
- 使用特殊用途(有限用途)实时OS
多媒体系统
- 数据流必须根据时间限制传送
手持系统
- 如PDA、智能手机
- CPU、内存和电源有限
- 过去使用功能简化的OS
点对点计算
- 分布式系统的另一种模型
- P2P不区分客户端和服务器
- 所有节点都被视为对等体
- 可以充当客户端、服务器或两者
- 节点必须加入P2P网络:
- 向中央查找服务注册其服务,或
- 通过发现协议广播请求和响应服务
- 示例:BitTorrent、Napster、Gnutella和区块链平台
操作系统操作
多道程序设计(Multiprogramming)
基本概念
- 多道程序设计对于效率是必要的
- 单个用户无法始终保持CPU和I/O设备忙碌
- 用户的计算任务被组织为作业(代码和数据)
工作机制
- 作业调度:内核调度作业,使CPU始终有事可做
- 内存管理:系统中作业的子集保存在内存中
- 作业切换:当作业必须等待(如I/O)时,内核切换到另一个作业
多任务(Multitasking)
时间共享概念
- **时间共享(多任务)**扩展了多道程序设计
- OS频繁切换作业,用户可以与每个正在运行的作业交互
- 响应时间应该< 1秒
特征
- 每个用户至少有一个程序在内存中执行(进程)
- CPU调度:如果几个作业同时准备运行
- 虚拟/物理内存:使程序员更容易
双模式操作
基本概念
- 操作系统通常是中断驱动的
- 效率,重新获得控制(定时器中断)
- 双模式操作允许OS保护自身和其他系统组件
模式类型
- 用户模式和内核模式(或其他名称)
- 模式位区分CPU是在运行用户代码还是内核代码
- 特权指令:一些指令被指定为特权的,只能在内核中执行
- 系统调用:将模式改为内核,从调用返回将其重置为用户
模式间转换
- 系统调用、异常、中断导致内核/用户模式之间的转换
定时器(Timer)
- 防止无限循环或进程占用资源
- 启用定时器:设置硬件在某个时间段后中断
- OS设置定时器:在调度进程之前设置定时器以重新获得控制
- 调度定时器:通常是周期性的(如250Hz)
- 无滴答内核:按需定时器中断(Linux)
资源管理
进程管理
进程基本概念
- 进程是正在执行的程序
- 程序是被动实体,进程是活动实体
- 系统有许多进程并发运行
从程序到进程
- 程序:存储在磁盘上的被动代码
- 进程:程序装载到内存后的活动实体
- 进程需要资源来完成其任务:
- CPU、内存、I/O、文件、初始化数据等
- 资源回收:进程终止时,OS回收所有可重用资源
进程管理活动
- 进程创建和终止
- 进程挂起和恢复
- 进程同步原语
- 进程通信原语
- 死锁处理
从进程到线程
- 单线程进程有一个程序计数器
- 程序计数器指定下一条要执行的指令的位置
- 处理器按顺序执行指令,一次一条,直到完成
- 多线程进程每个线程有一个程序计数器
- 线程的好处:
- 创建开销小
- 上下文切换快
- 共享内存空间
- 并发执行
内存管理
内存管理基本概念
- 内存是CPU可直接访问的主要存储
- 数据处理前后都需要保存在内存中
- 所有指令都应该在内存中才能执行
内存管理目标
- 优化CPU利用率和响应时间
- 为程序员提供虚拟内存视图
内存管理活动
- 跟踪内存的哪些部分正在被使用以及被谁使用
- 决定哪些进程和数据移入和移出内存
- 分配和释放根据需要分配和释放内存空间
文件系统管理
文件系统基本概念
- OS提供统一的逻辑数据存储视图
- 文件是抽象物理属性的逻辑存储单元
- 文件通常组织到目录中
- 访问控制决定谁可以访问文件
文件系统管理活动
- 创建和删除文件和目录
- 操作原语来操作文件和目录
- 映射文件到辅助存储
- 备份文件到稳定(非易失性)存储介质
大容量存储管理
基本概念
- 磁盘子系统管理大容量存储
- 磁盘用于存储:
- 不适合主内存的数据
- 必须保存"长"时间的数据
- 整个系统速度取决于磁盘子系统及其算法
- 某些存储不需要快速(如光存储或磁带)
大容量存储管理活动
- 空闲空间管理
- 存储分配
- 磁盘调度
数据迁移通过存储层
- 系统必须使用最新值,无论它存储在哪里
- 多级数据一致性:
- 多处理器的缓存一致性(缓存窥探):由硬件实现
- 所有CPU在其缓存中都有最新值
- 多进程或多线程的同步
- 分布式环境情况更复杂
- 一个数据可能存在多个副本:如何同步更改?
I/O系统管理
I/O子系统职责
- I/O子系统向用户隐藏硬件设备的特性
- I/O子系统负责:
- 管理I/O内存
- 缓冲:在数据传输时临时存储数据
- 缓存:在更快存储中存储数据部分以提高性能
- 假脱机:一个作业的输出与其他作业的输入重叠
设备驱动程序接口
- OS可能提供通用设备驱动程序接口
- 优点:对程序员好:面向对象设计模式
- 缺点:从安全角度看:大量使用函数指针
操作系统设计原则
策略与机制分离
基本概念
- 机制(Mechanism):关于系统"如何"的问题
- 操作系统如何执行上下文切换
- 策略(Policy):“哪个"问题
- 应该切换到哪个进程
其他示例
- 机制示例:
- 如何分配内存
- 如何调度CPU
- 如何处理中断
- 策略示例:
- 哪个进程获得内存
- 哪个进程优先运行
- 哪个中断优先处理
优势与劣势
- 优势:
- 灵活性:可以更改策略而不改变机制
- 模块化:清晰的分层设计
- 可维护性:更容易理解和修改
- 劣势:
- 性能开销:额外的抽象层
- 复杂性:需要更仔细的设计
虚拟化
虚拟化概念
- 抽象单个计算机的硬件(CPU/内存/IO等)到不同环境
- 虚拟机:提供与底层硬件相同接口的软件
- 好处:
- 资源共享
- 隔离性
- 可移植性
- 易于管理
虚拟化类型
- 完全虚拟化:完全模拟硬件
- 半虚拟化:修改客户OS以与虚拟机监控器协作
- 硬件辅助虚拟化:硬件支持虚拟化
抽象
抽象的重要性
抽象是我们在计算机科学中所做的一切的基础
抽象使以下成为可能:
- 编写大型程序:将其分为小而可理解的片段
- 使用高级语言:如C语言编写而不考虑汇编
- 汇编编程:而不考虑逻辑门
- 构建处理器:使用门而不过多考虑晶体管
抽象层次
- 应用程序层:用户程序
- 高级语言层:C/C++/Java等
- 汇编语言层:汇编指令
- 指令集架构层:机器指令
- 微架构层:CPU内部实现
- 逻辑门层:数字逻辑
- 晶体管层:物理实现
操作系统框架
操作系统服务组成
- 用户可见服务
- 用户界面(UI)
- 包括:CLI(Command-Line, 命令行), GUI(Graphic User Line, 图形化用户界面), batch
- 程序运行
- I/O操作
- 文件系统操作
- 通信
- 错误检测
- 用户界面(UI)
- 系统可见服务
- 资源分配
- 包括:CPU调度,内存分配和管理,I/O设备分配
- 系统保护
- 会计统计
- 资源分配
系统调用(System Call)
定义
- 系统调用指的是访问操作系统服务的编程接口
示例
- Linux的复制指令
就是一个调用系统调用
1cp in.txt out.txt
调用
- 一般一个系统调用被与一个数字联系起来,这个数字被称为系统调用号(System Call Number)
- 例如Linux中read()可能是编号0,write()可能是编号1
- 系统调用接口表
- 系统调用接口维护着一个表格,这个表格被这些编号索引,表格中存储着对应系统调用处理函数的地址,类似于您文档中提到的中断向量表观念
- Linux系统调用数量示例
- Linux有大约340个系统调用,不同架构的系统调用数量略有差异。x86架构有349个系统调用,而ARM架构有345个
系统调用的核心原理
- 内核执行系统调用并返回结果
- 用户程序无需了解系统调用细节
- 用户只需使用API并理解其功能
- API隐藏操作系统接口的大部分细节
系统调用传参
寄存器法
- 工作原理
- 参数直接存储在CPU寄存器中
- 系统调用时,内核直接从寄存器读取参数
- 优势
- 速度最快
- 实现简单
- 开销最小
- 劣势
- 参数数量首先
- 不适合复杂调用
- 内存块法
- 工作原理
- 参数存储在内存块(或表)中
- 内存块的地址作为参数传递给寄存器
- 内核通过地址访问内存块获取所有参数
- 优势
- 参数数量不受限制:内存块可以很大
- 适合复杂数据结构:可以传递结构体、数组等
- 组织性好:参数集中管理
- 劣势
- 需要额外内存访问
- 实现稍复杂
- 栈法
- 工作原理
- 参数被程序推入栈中
- 操作系统从栈中弹出参数
- 利用栈的后进先出特性
- 优势
- 参数数量不受限制
- 自然的调用约定
- 易于实现
- 劣势
- 栈操作开销
- 栈空间管理
- 工作原理
Linux/x86架构下execve系统调用的实现
- 存储系统调用信号到eax寄存器
- 参数存储到指定寄存器
- 执行系统调用指令
- 完整汇编代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21section .data filename db '/bin/ls', 0 arg1 db 'ls', 0 arg2 db '-l', 0 argv dd filename, arg1, arg2, 0 envp dd 0 section .text global _start _start: mov eax, 11 mov ebx, filename mov ecx, argv mov edx, envp int 0x80 mov eax, 1 mov ebx, -1 int 0x80
系统调用列举
- 进程控制
- Types of System Calls
- Process control
- create process, terminate process
- end, abort
- load, execute
- get process attributes, set process attributes
- wait for time
- wait event, signal event
- allocate and free memory
- Dump memory if error
- Debugger for determining bugs, single step execution
- Locks for managing access to shared data between processes
- 文件管理
- create file, delete file
- open, close file
- read, write, reposition
- get and set file attributes
- 设备管理
- request device, release device
- read, write, reposition
- get device attributes, set device attributes
- logically attach or detach devices
- can be combined with file management system call
- 信息维护
- get time or date, set time or date
- get system data, set system data
- get and set process, file, or device attributes
- 通信
- create, delete communication connection
- send, receive messages: message passing model to host name or process name
- From client to server
- Shared-memory model create and gain access to memory regions
- transfer status information
- attach and detach remote devices
- 保护
- Control access to resources
- Get and set permissions
- Allow and deny user access
应用程序接口(Application Programming Interface, API)
定义:
- 应用程序编程接口,是预先定义的函数/集合的集合
常用的API
- Win32: Windows
- POSIX: UNIX, Linux
- Java: Java虚拟机
链接器(Linker)与加载器(Loader)
基本概念
链接器
- 功能:将目标文件转换为可执行文件
- 作用:解决符号引用,合并代码段和数据段、
- 时机:编译时或程序启动时
加载器
- 功能:将程序转换为进程
- 作用:将可执行文件加载到内存并启动执行
- 时机:程序执行时
工作方式和内容
编译链接过程
链接类型对比
- 静态链接
- 特点
- 链接时机:编译时完成所有链接
- 文件大小:较大,包含所有依赖库
- 运行依赖:无外部依赖,独立运行
- 优点
- 运行时无依赖
- 加载速度快
- 部署简单
- 缺点
- 文件体积大
- 内存占用多
- 库更新需要重新编译
- 特点
- 动态链接
- 特点
- 链接时机:运行时动态链接
- 文件大小:较小,只包含引用信息
- 运行依赖:需要动态链接库(DLL/SO)
- 优点:
- 文件体积小
- 内存共享
- 库更新无需重新编译
- 节省磁盘空间
- 缺点:
- 运行时有依赖
- 加载稍慢
- 部署复杂
- 特点
- 注:延迟绑定(Lazy Binding)
- 概念
- 定义:动态链接库中的函数在第一次调用时才进行地址解析
- 目的:减少程序启动时间,只解析实际使用的函数
- 概念
操作系统架构
已有的操作系统架构
MS-DOS
- 架构特点:简单的单体结构
- 特征:
- 应用程序可以直接访问硬件
- 没有明确的用户模式和内核模式分离
- 程序运行在单一地址空间
- 优点:
- 系统开销小
- 执行效率高
- 实现简单
- 缺点:
- 系统不稳定,一个程序崩溃可能导致整个系统崩溃
- 安全性差
- 不支持多任务
Original-UNIX
- 架构特点:经典的分层单体内核
- 特征:
- 内核和用户程序分离
- 系统调用作为内核和用户程序的接口
- “一切皆文件"的设计理念
- 优点:
- 简洁而强大的设计
- 良好的可移植性
- 多用户多任务支持
- 缺点:
- 内核代码耦合度高
- 难以扩展和维护
- 单体内核的性能瓶颈
分层方法(Layered Approach)
- 基本概念:
- 操作系统被划分为多个层次(levels)
- 每一层都建立在较低层之上
- 最底层(第0层)是硬件,最高层(第N层)是用户界面
- 每一层只使用较低层的函数和服务
- THE操作系统分层示例:
1 2 3 4 5 6第5层: 用户程序 第4层: 输入/输出管理 第3层: 操作员-进程通信 第2层: 内存管理 第1层: 进程调度 第0层: 硬件 - 优点:
- 模块化设计,便于调试和维护
- 层次清晰,易于理解
- 易于验证系统正确性
- 缺点:
- 性能开销大(多层调用)
- 层次划分困难
- 严格分层限制系统灵活性
微内核方法(Microkernel Approach)
- 基本概念:
- 将尽可能多的功能从内核移到用户空间
- 内核只保留最基本的功能
- 其他系统服务作为用户级进程运行
- 微内核核心功能:
- 进程间通信(IPC)
- 基本进程管理
- 低级内存管理
- 基本I/O和中断管理
- 用户空间服务:
- 文件系统服务器
- 网络协议栈
- 设备驱动程序
- 虚拟内存管理器
- 优点:
- 系统稳定性高(服务崩溃不影响内核)
- 安全性好(服务运行在隔离的地址空间)
- 易于扩展和维护
- 支持分布式系统
- 缺点:
- IPC开销大,性能较低
- 系统调用开销增加
- 设计和实现复杂
模块化方法(Modular Approach)
- 基本概念:
- 结合单体内核和微内核的优点
- 内核提供核心服务
- 其他功能通过可装载模块实现
- 特征:
- 模块可以动态加载和卸载
- 模块运行在内核空间
- 通过定义良好的接口通信
- Linux模块示例:
- 文件系统模块(ext4, ntfs)
- 网络协议模块(TCP/IP)
- 设备驱动模块
- 优点:
- 灵活性高
- 内存使用效率高
- 易于维护和扩展
- 性能好(避免用户空间切换)
- 缺点:
- 模块错误可能影响整个内核
- 接口设计需要谨慎
- 依赖关系管理复杂
混合系统架构
- 基本概念:
- 结合多种架构方法的优点
- 针对不同功能采用最适合的架构
- 现代操作系统实例:
- Windows NT:混合微内核架构
- 内核模式:HAL、内核、执行体
- 用户模式:子系统、应用程序
- macOS:基于Mach微内核的混合架构
- Mach微内核 + BSD层 + I/O Kit
- Linux:模块化单体内核
- 单体内核 + 可装载模块
- Windows NT:混合微内核架构
系统调用实例
进程管理系统调用示例
fork系统调用
- 基本概念:创建新进程的方式
- 特殊之处:
- 新创建的进程是调用进程的完全副本
- 返回两次:在父进程和子进程中分别返回
- 新进程拥有自己的内存地址空间
- 返回值:
- 在父进程中:返回子进程的PID
- 在子进程中:返回0
- 出错时:返回-1
fork + wait组合
- wait系统调用:父进程等待子进程执行完毕
- 用途:
- 避免僵尸进程
- 获取子进程退出状态
- 进程同步控制
- 典型使用模式:
1 2 3 4 5 6 7 8pid_t pid = fork(); if (pid == 0) { // 子进程代码 exit(0); } else if (pid > 0) { // 父进程代码 wait(NULL); // 等待子进程结束 }
fork + wait + exec组合
- exec系统调用特点:
- 用于运行与调用程序不同的程序
- exec永不返回(成功时)
- 完全替换当前进程映像
- 为什么分离fork和exec:
- 构建UNIX shell的基础
- 允许在fork后、exec前进行特殊操作
- 提供更大的灵活性
- Shell工作原理:
- Shell是一个用户程序
- 等待用户输入
- 执行命令:fork创建子进程 → exec加载新程序 → wait等待完成
- 分离设计使shell功能更强大
调试相关系统调用
ptrace系统调用
- 基本概念:进程追踪系统调用
- 主要功能:
- 一个进程可以控制另一个进程的执行
- 检查和修改被追踪进程的内存和寄存器
- 实现断点调试功能
- 应用场景:
- 调试器实现:gdb、strace等工具的基础
- 进程监控和分析
- 安全分析工具
调试器(Debugger)工作原理
- 定义:用于测试和调试其他程序的计算机程序
- 基本操作:
- 附加到进程(Attaching to a process)
- 基本控制(Basic Control):暂停、继续、单步执行
- 设置断点(Setting a breakpoint)
- 命中断点(Hitting a breakpoint)
- ptrace在调试中的应用:
- 通过ptrace系统调用实现进程控制
- 监控被调试程序的每个系统调用
- 提供程序执行状态的实时查看
系统调用实践要点
- 进程创建模式:fork + exec是UNIX系统进程创建的标准模式
- Shell实现:所有UNIX shell都基于fork/exec/wait三个系统调用
- 调试工具:现代调试器和追踪工具都依赖ptrace系统调用
- 手册参考:使用man page查看详细的系统调用文档和使用方法