第 1 章 操作系统简介
1.1 什么是操作系统
操作系统是一个或多个程序的集合,其提供了一系列的服务,是应用程序与计算机硬件之间的接口,其在多个进程中分配和管理资源的共享。
1.1.1 资源管理者
1.1.2 服务提供者
1.1.3 虚拟机
1.2 操作系统的功能
1.2.1 进程
当管理 CPU 资源时,通常根据正在运行的程序来进行管理。在执行时,我们将这些程序称之为进程(processes)。为了支持进程,操作系统通常提供如下服务:
- 创建进程
- 终止进程
- 改变进程优先级
- 提供进程间通信
- 提供进程同步
在内部,操作系统负责调度(scheduling)和上下文切换(context switching)。调度程序是一种机制,通过这种机制,操作系统选择下一个将要运行的进程。一个进程将 CPU 控制权转交给另一个进程的实际操作称为上下文切换。
1.2.2 存储器
系统的性能更依赖于存储管理子系统的行为。存储管理的核心是对分配和释放内存的请求做出响应。建立典型存储管理服务集基础的功能如下:
- 直接请求额外内存
- 直接请求内存(当创建新进程时等情况下)
- 释放内存并返还给操作系统
- 请求进程间得共享内存区
在大多数环境中,我们要满足更多的内存请求,而不止计算机上实际安装的内存。这种过度分配通常称为虚拟存储器(virtual memory)。
1.2.3 I/O 设备
在管理 I/O 设备中,通常为进程提供各种各样的服务,这些服务通常包括:
- 向进程开放设备或附加设备
- 从设备中读取数据
- 往设备写入数据
- 关闭与释放设备
- 对合适设备提供独占访问
- 提供各种各样的特定功能,如复卷磁带和设置串行线路传输速率
1.2.4 文件系统
我们使用 I/O 设备来支持的另一个功能是文件系统(file system)。在大多数情况下,文件系统支持的请求集与 I/O 设备子系统相似:
- 打开文件
- 读文件
- 写文件
- 关闭文件
- 在文件中搜索随机位置
- 读取文件元数据(如文件名、大小、所有者、保护码等)
- 修改已选中的元数据
1.2.5 安全性
操作系统绝不允许任何进程终止另一个进程。除了后台的强制运行机制之外,应用程序能请求的服务如下:
- 设置安全性策略
- 查询安全性策略
- 验证自身的远程系统
- 侦听远程系统来验证自身
- 加密/解密消息,特别是经由网络的消息
1.2.6 联网
在大多数情况下,联网支持是 I/O 子系统的另外一个应用。I/O 设备除了负责数据位在系统的输入输出之外,操作系统还能标准的实现协议栈。将网络协议设计成若干层是很常见的,每层封装其它层。和 I/O 编程一样,有必要让操作系统负责这些协议。从应用程序的角度来看,网络服务应该包括:
- 与远程服务建立连接
- 从远程客户端侦听连接
- 往远程系统发送消息
- 从远程系统接收消息
- 关闭与远程系统的连接
1.2.7 用户接口
与只处理硬件和操作系统的其他功能相比,处理用户相关的问题时,事情往往变得更复杂,因此,用户接口是需要研究的一个大主题。
1.3 操作系统的历史
1.3.1 裸机
1.3.2 批处理操作系统
作业可以以某种交互会话的形式进行提交,提交的作业仍作为批的一部分运行,以这种方式操作的操作系统称为批处理操作系统(batch operating system)。批处理操作系统突破了一个用户这个限制。尽管在任何时刻,计算机只为一个用户工作,但在使用所有计算设备的过程中有许多用户存在。
1.3.3 分时操作系统
分时操作系统(time-sharing operating system)、多道程序操作系统(multiprogramming operating system)或多任务操作系统(multitasking operating system)。这类新型操作系统突破了一个程序这个限制。
1.3.4 分布式操作系统
分布式操作系统(distributed operating system)。一些具有多个 CPU 的计算机共享单一物理内存和相同的 I/O 设备,我们将这类计算机称为对称多处理(symmetric multiprocessing,SMP)系统。
1.4 组织操作系统的技术
1.4.1 单块设计
单块(monolithic)设计。一般认为这类设计的特点是缺乏任何其他的组织形式,但在现实中,单块设计恰好是将设计组织为单个程序。与任何程序一样,这样的设计具有良好的组织结构。大多数操作系统是沿着这个思路进行组织的。
1.4.2 分层设计
分层设计的基本思想是:每层增加抽象层,它建立再较低层提供的函数之上。Comer 教授开发的 XINU 操作系统是遵循分层设计的很好例子。
1.4.3 微内核设计
一些设计师认为应该将许多传统的核心功能从内核移到其他进程中去,而这些进程由内核进行管理。原则上,这将使内核更小、更容易编写和维护。在这种设计中,在单块内核中通过函数调用完成的许多工作都是要使用微内核的消息传递来处理的。微内核设计影响组件间的通信,本可以通过参数传递或共享变量进行的通信都必须由消息进行传递。微内核操作系统设计的另一个挑战是安全性问题。
微内核设计很好的示例包括 Tanenbaum 教授的 MINIX、Hurd(部分的 GNU 环境来自软件基金会)和 Mach 操作系统,在一些其他用途中,Mash 教授作为 Mac OS X 的基础用于 Apple Macintosh。虽然 Inferno 不是围绕微内核构建的,但通过示例,我们会看到它是如何将一些传统功能转移用户进程的。
1.4.4 虚拟机设计
虚拟机操作系统的主要功能是提供硬件有许多副本的错觉。这种做法的典型例子是 IBM 的 VM 操作系统。使用户能同时运行多个操作系统的产品:商业产品 VMware,开源项目 Xen 等。另外一种方法是模拟,在软件中模拟一个完整的计算机,并在此模拟机上运行操作系统。例如:用来运行并行操作系统的 QEMU。
1.5 引导
系统从硬件到我们拥有运行操作系统的过程称为引导(bootstrapping)。虽然现在引导这个术语已经很常用,但许多制造商还使用其他术语来代替引导,例如:冷启动(cold start)、静启动(dead start)和初始程序加载(initial program load,IPL)。
有三种典型的方法解决引导问题:
*
1.6 系统调用
1.6.1 系统调用示例
1.6.2 系统调用机制
1.7 本章小结
1.8 练习
第 2 章 操作系统示例
2.1 兼容分时系统
2.1.1 组织结构
2.1.2 引导
2.2 多路信息和计算服务
2.2.1 组织结构
2.2.2 系统调用
2.3 RT-11
2.3.1 组织结构
2.4 第 6 版 UNIX
2.4.1 组织结构
2.4.2 系统调用
2.5 虚拟内存系统
2.5.1 组织结构
2.5.2 引导
2.5.3 系统调用
2.6 4.3 BSD
2.6.1 组织结构
2.6.2 系统调用
2.7 Windows NT
2.7.1 组织结构
2.8 TinyOS
2.8.1 组织结构
2.9 Xen
2.9.1 组织结构
2.10 本章小结
2.11 练习
第 3 章 Inferno 的结构与初始化
3.1 Inferno 的起源
3.2 基本概念
3.3 组织结构
3.3.1 基本体系结构
3.3.2 源代码组织结构
3.4 初始化
3.4.1 启动 Inferno
3.4.2 宿主操作系统的特定初始化
3.4.3 与宿主操作系统无关的初始化
3.4.4 启动分时
3.5 系统调用
3.6 本章小结
3.7 练习
第 4 章 Linux 的结构与初始化
4.1 Linux 的起源
4.2 组织结构
4.2.1 基本体系结构
4.2.2 模块
4.2.3 源代码组织结构
4.3 初始化
4.3.1 引导
4.3.2 特定处理器初始化
4.3.3 与处理器无关的初始化
4.3.4 启动分时
4.3.5 初始化管理级的初始化
4.4 系统调用
4.4.1 处理应用方得系统调用
4.4.2 处理内核方的系统调用
4.5 本章小结
4.6 练习
第 5 章 进程管理原理
5.1 进程的概念
5.2 实现进程
5.2.1 进程操作
5.2.2 进程状态
5.2.3 进程表
5.3 线程
5.4 调度
5.4.1 先来先服务
5.4.2 最短作业优先
5.4.3 轮转法
5.4.4 优先级调度
5.4.5 调整调度参数
5.4.6 两级调度
5.4.7 实时调度
5.4.8 嵌入式系统的调度
5.5 上下文切换
5.6 进程的创建与终止
5.7 临界区
5.7.1 中断控制
5.7.2 原子操作指令
5.7.3 Peterson 算法
5.7.4 信号量
5.7.5 管程
5.7.6 消息传递
5.7.7 示例
5.8 死锁
5.8.1 充分必要条件
5.8.2 处理死锁
5.9 本章小结
5.10 练习
第 6 章 进程管理示例
6.1 CTSS
6.1.1 进程状态
6.1.2 系统调用
6.1.3 调度
6.2 Multics
6.2.1 系统调用
6.2.2 进程状态
6.2.3 调度
6.3 RT-11
6.3.1 系统调用
6.3.2 进程状态
6.3.3 进程表
6.3.4 调度
6.4 第 6 版 UNIX
6.4.1 系统调用
6.4.2 进程状态
6.4.3 进程表
6.4.4 调度
6.5 4.3 BSD
6.5.1 系统调用
6.5.2 进程状态与进程表
6.5.3 调度
6.6 VMS
6.6.1 系统调用
6.6.2 进程状态
6.6.3 调度
6.7 Windows NT
6.7.1 系统调用
6.7.2 进程状态
6.7.3 进程表与线程表
6.7.4 调度
6.8 TinyOS
6.9 Xen
6.10 本章小结
6.11 练习
第 7 章 Inferno 中的进程管理
7.1 Inferno 中的进程
7.2 进程的状态
7.2.1 内核进程
7.2.2 用户进程
7.3 进程的数据结构
7.3.1 内核进程表
7.3.2 内核进程表项
7.3.3 用户进程表
7.3.4 用户进程表项
7.4 进程的创建
7.4.1 解释进程创建指令
7.4.2 实现进程创建
7.5 进程的终止
7.6 进程调度
7.6.1 插入就绪表
7.6.2 从就绪表中删除
7.6.3 分时
7.6.4 运行时间片
7.7 本章小结
7.8 练习
第 8 章 Linux 中的进程管理
8.1 进程与线程
8.1.1 Linux 中的内核线程
8.1.2 进程间的关系
8.2 系统调用
8.3 进程状态
8.4 进程表
8.5 进程的创建
8.5.1 处理系统调用
8.5.2 创建进程
8.5.3 特定体系结构的步骤
8.6 进程调度
8.6.1 优先级
8.6.2 队列结构
8.6.3 时钟计时单元
8.6.4 调度程序
8.7 本章小结
练习
第 9 章 存储管理原理
9.1 存储层次结构
9.2 地址变换
9.2.1 基址/上下界寄存器
9.2.2 分段存储
9.2.3 分页存储
9.3 存储相关的服务
9.4 存储布局
9.5 内存分配技术
9.5.1 空闲空间管理
9.5.2 碎片
9.5.3 分区
9.5.4 选择策略
9.5.5 伙伴系统管理
9.6 过度分配技术
9.6.1 交换
9.6.2 段交换
9.6.3 分页
9.6.4 段页式
9.6.5 内存映射文件
9.6.6 写时复制
9.6.7 性能问题
9.7 嵌入式系统的存储管理
9.8 本章小结
练习
第 10 章 存储管理示例
10.1 CTSS
10.2 Multics
10.2.1 存储相关的系统调用
10.2.2 存储布局
10.2.3 段式管理与页式管理
10.3 RT-11
10.3.1 存储相关的系统调用
10.3.2 存储布局
10.3.3 USR 与 KMON 交换
10.4 第 6 版 UNIX
10.4.1 存储相关的系统调用
10.4.2 存储布局
10.4.3 空闲空间管理
10.4.4 分配
10.4.5 交换
10.5 4.3 BSD
10.5.1 存储相关的系统调用
10.5.2 存储布局
10.5.3 空闲空间管理
10.5.4 交换与页替换
10.6 VMS
10.6.1 页表
10.6.2 存储布局
10.6.3 空闲空间管理
10.6.4 交换与页替换
10.6.5 存储相关的系统调用
10.7 Windows NT
10.7.1 系统调用
10.7.2 存储布局
10.7.3 页式管理
10.8 TinyOS
10.9 Xen
10.9.1 超级调用
10.9.2 存储布局
10.9.3 页式管理
10.10 本章小结
练习
第 11 章 Inferno 中的存储管理
11.1 概述
11.2 存储布局
11.3 存储管理的数据结构
11.3.1 存储池
11.3.2 存储块
11.4 存储管理的实现
11.4.1 分配内存
11.4.2 从树中删除空闲块
11.4.3 释放内存
11.4.4 把空闲块插入树中
11.5 垃圾收集
11.5.1 堆结构
11.5.2 引用计数
11.5.3 并发垃圾收集器
11.5.4 实现并发垃圾收集
11.6 本章小结
11.7 练习
第 12 章 Linux 中的存储管理
12.1 存储布局
12.2 系统调用
12.3 分配机制
12.3.1 管理区页的分配
12.3.2 slab 分配器
12.3.3 内核的内存分配
12.4 页管理
12.4.1 页表
12.4.2 页替换
12.5 存储管理的数据结构
12.5.1 进程分配的表示
12.5.2 虚拟内存区表示
12.6 存储管理的实现
12.6.1 处理分配系统调用
12.6.2 增加区域
12.6.3 处理缺页
12.6.4 解决缺页错误
12.6.5 处理新页面
12.7 本章小结
12.8 练习
第 13 章 I/O 设备管理原理
13.1 I/O 子系统的要素
13.2 I/O 设备的硬件特性
13.2.1 磁盘驱动器
13.2.2 串口通信
13.2.3 控制器接口技术
13.3 I/O 设备类型
13.3.1 通信设备与存储设备
13.3.2 流设备与块设备
13.4 I/O 子系统设计的目标
13.5 I/O 设备服务
13.6 设备驱动器的结构
13.7 设备管理技术
13.7.1 缓冲区
13.7.2 交叉存取
13.7.3 电梯算法
13.7.4 RAID
13.7.5 水位标志
13.7.6 人工输入处理
13.7.7 伪设备
13.8 本章小结
13.9 练习
第 14 章 I/O 设备管理示例
14.1 CTSS
14.2 Multics
14.3 RT-11
14.4 第 6 版 UNIX
14.5 4.3 BSD
14.6 VMS
14.7 Windows NT
14.8 TinyOS
14.9 Xen
14.10 本章小结
14.11 练习
第 15 章 Inferno 中的 I/O 设备
15.1 设备驱动程序结构
15.2 并行端口支持
15.2.1 为写请求服务
15.2.2 写入单字节
15.3 键盘支持
15.3.1 初始化键盘控制器
15.3.2 处理键盘中断
15.4 IDE 磁盘支持
15.4.1 处理 I/O 请求
15.4.2 初始化 IDE 控制器操作
15.4.3 处理 IDE 控制器中断
15.5 本章小结
15.6 练习
第 16 章 Linux 中的 I/O 设备
16.1 块请求支持
16.2 两半中断处理程序结构
16.3 并行端口驱动程序
16.3.1 处理系统调用
16.3.2 选择合适的底层写入
16.3.3 从缓冲区写入字节
16.3.4 配置控制器
16.4 软盘驱动程序
16.4.1 处理请求
16.4.2 调度软盘操作
16.4.3 执行软盘操作
16.4.4 启动命令
16.4.5 准备数据传输
16.4.6 控制器编程
16.4.7 处理软盘中断
16.4.8 完成软盘操作
本章小结
练习
第 17 章 文件系统原理
17.1 文件系统服务
17.1.1 共享与独占访问
17.1.2 访问模式
17.1.3 文件结构
17.1.4 元数据
17.1.5 内存映射文件
17.2 总体文件系统设计
17.2.1 文件系统形式
17.2.2 主要数据结构
17.3 名称空间
17.3.1 驱动器指示符
17.3.2 账户说明符
17.3.3 分层命名
17.3.4 文件扩展名
17.3.5 文件版本
17.3.6 特殊文件与目录
17.3.7 相对路径名与绝对路径名
17.4 管理存储空间
17.4.1 文件系统元数据
17.4.2 数据单位
17.4.3 空闲空间管理
17.4.4 普通文件
17.4.5 稀疏文件
17.4.6 分支
17.4.7 目录
17.4.8 别名
17.5 一致性检测
17.6 日志与日志结构的文件系统
17.7 块高速缓存
17.8 本章小结
17.9 练习
第 18 章 文件系统示例
18.1 CTSS
18.1.1 第一个 CTSS 文件系统
18.1.2 第二个 CTSS 文件系统
18.2 Multics
18.3 RT-11
18.4 第 6 版 UNIX
18.5 4.3 BSD
18.6 VMS
18.7 Windows NT
18.8 本章小结
18.9 练习
第 19 章 Inferno 中的文件系统
19.1 文件服务器的作用
19.1.1 Styx 协议
19.1.2 内置内核文件系统
19.1.3 用户空间文件服务器
19.2 根设备服务器
19.2.1 提供命名服务
19.2.2 遍历根服务器树
19.2.3 从根服务器读取
19.3 通用 Styx 消息处理程序
19.3.1 创建目录项
19.3.2 生成命名
19.3.3 遍历目录树
19.4 本地 Inferno 文件系统
19.4.1 初始化
19.4.2 主服务进程
19.4.3 处理 Styx 请求
19.4.4 遍历目录树
19.4.5 搜索目录
19.4.6 读文件
19.4.7 磁盘上的数据结构
19.4.8 读取目录项
19.4.9 读取文件块
19.4.10 查找文件块
19.4.11 处理间接块
19.4.12 从缓冲区高速缓存中获取
19.5 本章小结
19.6 练习
第 20 章 Linux 中的文件系统
20.1 虚拟文件系统
20.1.1 超级块
20.1.2 i- 节点
20.1.3 目录项
20.1.4 文件
20.2 EXT3 文件系统
20.3 EXT3 的磁盘结构
20.3.1 EXT3 超级块
20.3.2 EXT3-I 节点
20.3.3 EXT3 目录项
20.4 EXT3 命令查找
20.4.1 遍历路径
20.4.2 通用目录查找(第一部分)
20.4.3 通用目录查找(第二部分)
20.4.4 EXT3 目录查找
20.4.5 EXT3 目录搜索
20.4.6 EXT3 目录块搜索
20.5 写入文件
20.5.1 Linux 的写入系统调用
20.5.2 写入通用文件
20.5.3 写入 EXT3 文件
20.6 在 EXT3 中定位文件块
20.5.1 Linux 的写入系统调用
20.5.2 写入通用文件
20.5.3 写入 EXT3 文件
20.6 在 EXT3 中定位文件块
20.6.1 标识间接块
20.6.2 读取间接块
20.7 本章小结
20.8 练习
第 21 章 操作系统安全原理
21.1 用户认证
21.1.1 用户名与密码
21.1.2 散列函数加密
21.1.3 回调
21.1.4 挑战/响应认证
21.1.5 一次性密码
21.1.6 生物认证
21.2 基本资源保护
21.2.1 特权用户
21.2.2 访问 CPU 特性
21.2.3 内存访问
21.2.4 简单的代码保护
21.2.5 访问控制列表
21.2.6 权能
21.3 威胁类型
21.3.1 中间人攻击
21.3.2 特洛伊木马
21.3.3 陷阱门
21.3.4 逻辑/时间炸弹
21.3.5 病毒
21.3.6 蠕虫
21.3.7 隐蔽通道
21.3.8 拒绝服务
21.4 橙皮书分级
21.4.1 D 组
21.4.2 C 组
21.4.3 B 组
21.4.4 A 组
21.5 加密
21.5.1 对称加密
21.5.2 公钥加密学
21.6 Multics 的保护环
21.7 Inferno 的安全
21.8 Linux 的安全
21.9 本章小结
21.10 练习
第 22 章 分布式系统原理
22.1 基本概念
22.1.1 资源共享
22.1.2 同步操作
22.1.3 一致性
22.1.4 分布式互斥
22.1.5 容错
22.1.6 自稳定
22.2 处理器共享
22.2.1 对称多处理
22.2.2 集群
22.2.3 网格
22.3 分布式时钟
22.3.1 逻辑时钟
22.3.2 物理时钟
22.4 选举算法
22.4.1 欺负算法
22.4.2 环算法
22.5 本章小结
22.6 练习
附录 A 便于宿主 Inferno
A.1 建立配置
A.2 编译器与开发工具
A.3 PATH 环境变量
A.4 其他环境变量
A.5 编译系统
A.6 运行新版本
A.7 小结
附录 B 编译本地 Inferno
B.1 建立配置
B.2 创建工具链
B.3 创建引导程序代码
B.4 建立内核配置
B.5 生成加载程序配置
B.6 创建内核镜像
B.7 生成软盘镜像
B.8 运行新内核
B.9 小结
- 书名《操作系统原理、设计与应用》
- 英文名 Principle of Operating Systems:Design and Applications
- 书号 ISBN 978-7-302-22318-4
- Brian L. Stuart 著,葛秀慧 田浩 刘展威 等译
- 清华大学出版社
- 2010 年 6 月第 1 版第 1 次印刷