1.5 操作系统的结构
操作系统结构是指操作系统各个组成部分的组织方式和相互关系。随着计算机技术的发展,操作系统结构经历了从简单到复杂、从单一到模块化的演进过程。
简单结构(Monolithic Structure)
MS-DOS结构特点
基本特征 MS-DOS(Microsoft Disk Operating System)是早期个人计算机上广泛使用的操作系统,采用了最简单的操作系统结构。
结构组成
应用程序
|
系统程序 (COMMAND.COM)
|
MS-DOS设备驱动程序
|
ROM BIOS设备驱动程序
|
硬件
各层功能
- 应用程序层:用户编写的各种应用软件
- 系统程序层:命令解释器,提供用户界面
- MS-DOS驱动程序层:操作系统提供的设备驱动
- ROM BIOS层:基本输入输出系统,硬件抽象层
- 硬件层:物理硬件设备
设计特点
- 直接硬件访问:程序可以直接调用ROM BIOS或直接访问硬件
- 最小的结构:为了适应8086处理器的内存限制
- 功能有限:没有硬件保护,没有多任务支持
- 程序间无隔离:应用程序可以修改系统代码
早期Unix结构
基本架构 早期的Unix系统也采用类似的简单结构,但比MS-DOS更加复杂和完善。
用户程序
|
系统调用接口
|
内核 (Kernel)
- 文件系统
- CPU调度
- 内存管理
- 其他系统功能
|
硬件
特点分析
- 内核集中化:所有系统功能都集中在一个大内核中
- 效率较高:函数调用开销小,执行速度快
- 结构简单:便于理解和实现
- 维护困难:功能耦合度高,修改影响面大
优缺点分析
优势
-
性能优异
- 函数调用开销小
- 无需复杂的进程间通信
- 直接访问硬件,效率高
-
实现简单
- 设计和编码相对容易
- 调试和测试相对简单
- 适合资源受限的环境
-
功能集中
- 所有功能在同一地址空间
- 数据共享方便
- 控制流程清晰
劣势
-
可靠性差
- 任何模块的错误都可能导致系统崩溃
- 缺乏有效的保护机制
- 难以隔离故障
-
可维护性差
- 代码耦合度高
- 修改一个功能可能影响其他功能
- 难以进行模块化开发
-
可扩展性差
- 添加新功能困难
- 不利于系统升级
- 移植性较差
-
安全性低
- 缺乏访问控制
- 程序间无有效隔离
- 容易受到恶意攻击
分层结构(Layered Structure)
THE系统的分层思想
历史背景 THE(Technische Hogeschool Eindhoven)操作系统由荷兰学者Dijkstra在1968年设计,是第一个采用严格分层结构的操作系统。
分层设计原理 分层结构将操作系统组织成若干层次,每一层只能调用比它更低层次的服务,不能调用同层或更高层的服务。
THE系统的层次结构
第5层: 用户程序
第4层: 缓冲管理
第3层: 操作员-进程通信
第2层: 内存管理
第1层: CPU调度
第0层: 硬件
各层详细功能
第0层:硬件层
- 提供基本的硬件功能
- 中断处理机制
- 基本的I/O操作
第1层:CPU调度层
- 实现多道程序设计
- 进程切换和调度
- 时间片管理
- 为上层提供虚拟处理器
第2层:内存管理层
- 内存分配和回收
- 地址转换
- 内存保护
- 为上层进程提供虚拟内存
第3层:操作员-进程通信层
- 管理控制台输入输出
- 操作员与系统的交互
- 消息传递机制
第4层:缓冲管理层
- 管理I/O缓冲区
- 处理I/O请求队列
- 优化I/O操作效率
第5层:用户程序层
- 用户应用程序
- 系统实用程序
- 编译器和其他工具
分层结构的设计原则
单向依赖原则
- 每层只能调用下层提供的服务
- 不允许跨层调用
- 不允许向上调用
功能封装原则
- 每层有明确的功能边界
- 层间通过定义良好的接口通信
- 隐藏实现细节
抽象层次原则
- 从下到上抽象程度逐渐提高
- 下层为上层提供服务抽象
- 上层不需要了解下层实现细节
现代分层系统实例
网络协议栈
应用层 (HTTP, FTP, SMTP)
传输层 (TCP, UDP)
网络层 (IP)
数据链路层 (Ethernet)
物理层 (硬件)
操作系统内核分层
系统调用接口
文件系统层
内存管理层
进程管理层
设备驱动层
硬件抽象层
硬件层
优缺点分析
优势
-
模块化程度高
- 每层功能独立
- 便于分工开发
- 降低系统复杂度
-
易于调试和维护
- 可以逐层测试
- 错误定位容易
- 修改影响范围有限
-
易于理解
- 结构清晰明了
- 层次关系明确
- 便于教学和学习
-
可移植性好
- 只需修改底层
- 上层代码可重用
- 便于系统移植
劣势
-
性能开销大
- 多层调用开销
- 参数传递成本高
- 执行效率相对较低
-
设计困难
- 层次划分困难
- 功能分配复杂
- 需要仔细的系统设计
-
灵活性受限
- 严格的调用限制
- 难以处理跨层操作
- 某些优化难以实现
微内核结构(Microkernel Structure)
微内核的基本思想
核心理念 微内核结构将操作系统分为两部分:运行在内核态的微内核和运行在用户态的系统服务。微内核只保留最核心、最基本的功能,其他系统服务都移到用户空间。
设计哲学
- 最小化内核:内核只包含绝对必需的功能
- 用户态服务:大部分系统功能在用户态实现
- 消息传递:通过消息传递实现通信
- 模块化设计:各服务模块相对独立
微内核的核心功能
必须在内核态的功能
-
进程和线程管理
- 基本的进程创建和销毁
- 线程调度和切换
- 上下文切换
-
内存管理
- 基本的内存分配
- 地址空间管理
- 页表管理
-
进程间通信(IPC)
- 消息传递机制
- 同步原语
- 通信通道管理
-
基本I/O
- 中断处理
- 基本的设备访问
- DMA控制
移至用户态的服务
- 文件系统
- 设备驱动程序
- 网络协议栈
- 图形用户界面
- 安全服务
微内核系统架构
用户程序
|
+-- 文件系统服务 -- 设备驱动服务 -- 网络服务 --+
| |
+--------------- 消息传递 ---------------------+
| |
微内核 (进程管理、内存管理、IPC、中断处理)
|
硬件
消息传递机制
消息传递的重要性 在微内核系统中,由于各服务运行在不同的地址空间,必须通过消息传递进行通信。
消息传递过程
-
发送消息
send(destination, message);
-
接收消息
receive(source, message);
-
消息路由
- 微内核负责消息的路由
- 确保消息正确传递
- 提供同步和异步通信
消息类型
- 同步消息:发送方等待回复
- 异步消息:发送后立即返回
- 远程过程调用(RPC):模拟函数调用
典型微内核系统
Mach系统
- 卡内基梅隆大学开发
- 影响了许多后续系统
- MacOS X的Darwin内核基于Mach
主要特点
- 任务和线程概念
- 端口和消息传递
- 虚拟内存管理
- 机器无关性
QNX系统
- 商业实时微内核系统
- 广泛应用于嵌入式领域
- 高实时性和可靠性
核心特征
- 消息传递是唯一的IPC机制
- 所有服务都是独立进程
- POSIX兼容
- 网络透明性
Windows NT内核
- 混合内核架构(微内核+单内核)
- 关键服务在内核态
- Win32子系统在用户态
微内核的优缺点
优势
-
可靠性高
- 服务故障不会导致系统崩溃
- 故障隔离效果好
- 可以重启失效服务
-
安全性强
- 服务运行在用户态
- 权限分离明确
- 攻击面减小
-
可扩展性好
- 易于添加新服务
- 服务可以动态加载
- 支持分布式扩展
-
可移植性强
- 硬件相关代码少
- 便于移植到新平台
- 架构独立性好
-
易于调试
- 服务独立运行
- 可以单独调试服务
- 问题定位准确
劣势
-
性能开销大
- 消息传递开销高
- 用户态/内核态切换频繁
- 系统调用成本高
-
设计复杂
- 消息传递机制复杂
- 服务间协调困难
- 系统设计挑战大
-
开发难度高
- 需要重新设计系统服务
- 调试和测试复杂
- 开发周期长
模块化结构(Modular Structure)
现代操作系统的模块化设计
基本概念 模块化结构将操作系统设计为一组相对独立的模块,这些模块可以动态加载和卸载,提供了灵活性和可扩展性。
设计原则
- 高内聚,低耦合:模块内部功能相关,模块间依赖最小
- 接口标准化:模块间通过标准接口通信
- 动态配置:支持运行时加载和卸载模块
- 层次化组织:模块按功能层次组织
Linux内核模块化架构
Linux内核结构
用户空间
|
系统调用接口
|
+-- 进程管理 -- 内存管理 -- 文件系统 -- 网络 --+
| |
+-- 设备驱动 -- 架构相关代码 -- 可加载模块 ----+
| |
硬件抽象层
|
硬件
核心模块
-
进程管理模块
- 进程创建和销毁
- 调度算法实现
- 信号处理
-
内存管理模块
- 虚拟内存管理
- 页面分配器
- 内存映射
-
文件系统模块
- VFS(虚拟文件系统)
- 具体文件系统实现
- 缓存管理
-
网络模块
- 网络协议栈
- 套接字接口
- 网络设备驱动
可加载内核模块(LKM)
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init(void) {
printk(KERN_INFO "Hello, World!\n");
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "Goodbye, World!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple hello world module");
模块管理命令
# 加载模块
insmod hello.ko
# 查看已加载模块
lsmod
# 卸载模块
rmmod hello
# 查看模块信息
modinfo hello.ko
Windows驱动程序模型
Windows驱动架构
- 内核模式驱动程序:运行在内核态的驱动
- 用户模式驱动程序:运行在用户态的驱动
- 即插即用管理器:管理设备和驱动程序
驱动程序类型
- 总线驱动程序:管理总线控制器
- 功能驱动程序:控制具体设备
- 筛选驱动程序:提供附加功能
模块化的实现技术
动态加载技术
-
符号解析
- 解析模块中的外部符号
- 链接到内核符号表
- 处理符号依赖关系
-
重定位
- 调整模块中的地址引用
- 适应加载时的内存地址
- 修正跳转和调用指令
-
内存管理
- 为模块分配内存空间
- 设置合适的内存保护
- 管理模块的生命周期
接口标准化
// 设备驱动程序接口示例
struct device_driver {
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
int (*suspend)(struct device *dev);
int (*resume)(struct device *dev);
};
依赖管理
- 模块依赖关系描述
- 自动加载依赖模块
- 卸载时检查依赖关系
优缺点分析
优势
-
灵活性高
- 可以根据需要加载功能
- 支持系统定制
- 便于功能扩展
-
可维护性好
- 模块独立开发和测试
- 便于版本管理
- 易于排查问题
-
资源利用率高
- 按需加载,节省内存
- 不需要的功能可以不加载
- 支持热插拔
-
开发效率高
- 并行开发不同模块
- 代码重用率高
- 便于团队协作
劣势
-
复杂性增加
- 模块管理机制复杂
- 依赖关系复杂
- 调试困难
-
性能开销
- 动态加载开销
- 间接调用开销
- 内存碎片化
-
安全风险
- 恶意模块威胁
- 模块验证困难
- 权限控制复杂
混合结构(Hybrid Structure)
现代操作系统的混合特征
混合结构的必然性 现代操作系统通常不采用单一的结构模式,而是结合多种结构的优点,形成混合结构。
混合的原因
- 性能和安全的平衡
- 兼容性要求
- 工程实践的考虑
- 历史演进的结果
Windows NT架构分析
Windows NT系统架构
用户模式
+-- Win32应用程序 -- POSIX应用程序 -- OS/2应用程序 --+
| |
+-- Win32子系统 -- POSIX子系统 -- OS/2子系统 -----------+
| |
+-- 安全子系统 -- 其他环境子系统 ----------------------+
内核模式
+-- 系统服务 -- I/O管理器 -- 对象管理器 -- 安全管理器 --+
| |
+-- 进程管理器 -- 内存管理器 -- 缓存管理器 --------------+
| |
+-- 硬件抽象层(HAL) -- 设备驱动程序 -------------------+
| |
硬件
架构特点
-
微内核思想
- 环境子系统在用户态
- 消息传递机制
- 模块化设计
-
单内核实现
- 关键服务在内核态
- 提高性能
- 减少切换开销
-
分层结构
- 清晰的层次关系
- 硬件抽象层
- 服务层次化
核心组件
- 执行体(Executive):内核模式的系统服务
- 内核(Kernel):最底层的调度和同步机制
- 硬件抽象层(HAL):隐藏硬件差异
- 设备驱动程序:硬件设备的接口
macOS/Darwin架构
Darwin系统架构
应用程序 (Cocoa, Carbon, Java, POSIX)
|
+-- 应用框架 -- 图形服务 -- 核心服务 --+
| |
+-- BSD层 (系统调用, POSIX API) -------+
| |
+-- I/O Kit -- 内核扩展 ---------------+
| |
Mach微内核 (消息传递, 内存管理, 调度)
|
硬件
混合特征
- Mach微内核:提供基础服务
- BSD层:提供Unix兼容性
- I/O Kit:面向对象的驱动框架
- 内核扩展:可加载的内核模块
Linux内核的混合特性
Linux的结构特点 虽然Linux通常被称为单内核系统,但它实际上融合了多种结构特点:
-
单内核基础
- 核心功能在内核空间
- 高效的系统调用
- 紧密的功能集成
-
模块化扩展
- 可加载内核模块
- 动态功能扩展
- 灵活的配置选项
-
微内核思想
- 用户态辅助进程
- 消息队列机制
- 模块化设计
-
分层组织
- 清晰的抽象层次
- 硬件抽象层
- 子系统分层
容器和虚拟化架构
容器技术架构
容器应用 A | 容器应用 B | 容器应用 C
| | |
容器运行时 (Docker, containerd)
|
容器编排层 (Kubernetes)
|
宿主操作系统 (Linux)
|
硬件/虚拟化层
虚拟化架构
虚拟机A 虚拟机B 虚拟机C
客户OS 客户OS 客户OS
| | |
+-- 虚拟化层 (Hypervisor) --+
| |
宿主操作系统 (可选)
|
硬件
云原生操作系统
特点
- 为容器优化
- 最小化安装
- 自动更新机制
- 集群管理集成
代表系统
- Container Linux:专为容器设计的Linux发行版
- RancherOS:Docker作为系统级进程
- Atomic Host:Red Hat的容器主机OS
混合结构的优势
性能优化
- 关键路径在内核态执行
- 减少不必要的切换开销
- 针对性能热点优化
功能丰富
- 结合不同结构的优点
- 满足多样化需求
- 保持系统完整性
兼容性保证
- 支持多种应用环境
- 向后兼容性
- 标准接口支持
工程实用性
- 平衡理论和实践
- 渐进式改进
- 降低开发风险
未来发展趋势
更加模块化
- 功能组件化
- 插件式架构
- 动态重配置
智能化管理
- AI辅助优化
- 自适应调整
- 预测性维护
安全性增强
- 零信任架构
- 硬件安全支持
- 容器安全隔离
云原生集成
- 服务网格集成
- 边缘计算支持
- 多云管理能力
结构选择的权衡
设计考虑因素
性能要求
- 响应时间敏感 → 倾向单内核
- 吞吐量优先 → 可考虑分层结构
- 实时性要求 → 微内核或混合结构
可靠性要求
- 高可用性 → 微内核结构
- 故障隔离 → 模块化结构
- 系统稳定性 → 成熟的混合结构
安全性要求
- 高安全等级 → 微内核结构
- 权限分离 → 分层或模块化结构
- 攻击面最小化 → 精简内核
开发和维护
- 快速开发 → 简单结构
- 团队协作 → 模块化结构
- 长期维护 → 分层或混合结构
现代趋势
微服务化
- 系统功能服务化
- 容器化部署
- API驱动的架构
边缘计算适配
- 轻量化内核
- 快速启动
- 资源约束优化
人工智能集成
- 智能调度
- 自适应优化
- 预测性管理
通过对操作系统各种结构的深入理解,我们可以更好地理解现代操作系统的设计思想和实现方式,为选择和使用操作系统提供理论基础。