第一部分 概论 2
第1章 导论 2
1.1 操作系统的功能 2
1.1.1 用户视角 2
1.1.2 系统视角 3
1.1.3 操作系统的定义 4
1.2 计算机系统的组成 4
1.2.1 计算机系统的运行 5
1.2.2 存储结构 6
1.2.3 I/O结构 8
1.3 计算机系统的体系结构 9
1.3.1 单处理器系统 9
1.3.2 多处理器系统 10
1.3.3 集群系统 12
1.4 操作系统的结构 13
1.5 操作系统的执行 14
1.5.1 双重模式与多重模式的执行 15
1.5.2 定时器 16
1.6 进程管理 17
1.7 内存管理 18
1.8 存储管理 18
1.8.1 文件系统管理 18
1.8.2 大容量存储器管理 19
1.8.3 高速缓存 19
1.8.4 I/O系统 21
1.9 保护与安全 21
1.10 内核数据结构 22
1.10.1 列表、堆栈及队列 22
1.10.2 树 23
1.10.3 哈希函数与哈希表 23
1.10.4 位图 24
1.11 计算环境 24
1.11.1 传统计算 24
1.11.2 移动计算 25
1.11.3 分布计算 26
1.11.4 客户机-服务器计算 26
1.11.5 对等计算 27
1.11.6 虚拟化 28
1.11.7 云计算 29
1.11.8 实时嵌入式系统 30
1.12 开源操作系统 31
1.12.1 历史 31
1.12.2 Linux 31
1.12.3 BSD UNIX 32
1.12.4 Solaris 32
1.12.5 用作学习的开源操作系统 33
1.13 小结 33
习题 35
推荐读物 36
参考文献 36
第2章 操作系统结构 38
2.1 操作系统的服务 38
2.2 用户与操作系统的界面 40
2.2.1 命令解释程序 40
2.2.2 图形用户界面 41
2.2.3 界面的选择 42
2.3 系统调用 43
2.4 系统调用的类型 46
2.4.1 进程控制 46
2.4.2 文件管理 49
2.4.3 设备管理 50
2.4.4 信息维护 50
2.4.5 通信 50
2.4.6 保护 51
2.5 系统程序 51
2.6 操作系统的设计与实现 52
2.6.1 设计目标 52
2.6.2 机制与策略 53
2.6.3 实现 53
2.7 操作系统的结构 54
2.7.1 简单结构 54
2.7.2 分层方法 55
2.7.3 微内核 56
2.7.4 模块 57
2.7.5 混合系统 58
2.8 操作系统的调试 60
2.8.1 故障分析 60
2.8.2 性能优化 60
2.8.3 DTrace 61
2.9 操作系统的生成 63
2.10 系统引导 64
2.11 小结 64
习题 65
编程题 66
编程项目 66
推荐读物 69
参考文献 69
第二部分 进程管理 72
第3章 进程 72
3.1 进程概念 72
3.1.1 进程 72
3.1.2 进程状态 73
3.1.3 进程控制块 73
3.1.4 线程 74
3.2 进程调度 75
3.2.1 调度队列 75
3.2.2 调度程序 77
3.2.3 上下文切换 78
3.3 进程运行 79
3.3.1 进程创建 79
3.3.2 进程终止 82
3.4 进程间通信 83
3.4.1 共享内存系统 85
3.4.2 消息传递系统 86
3.5 IPC系统例子 89
3.5.1 例子:POSIX共享内存 89
3.5.2 例子:Mach 91
3.5.3 例子:Windows 92
3.6 客户机/服务器通信 93
3.6.1 套接字 93
3.6.2 远程过程调用 96
3.6.3 管道 98
3.7 小结 102
习题 103
编程题 105
编程项目 107
推荐读物 110
参考文献 110
第4章 多线程编程 112
4.1 概述 112
4.1.1 动机 112
4.1.2 优点 113
4.2 多核编程 114
4.2.1 编程挑战 115
4.2.2 并行类型 115
4.3 多线程模型 116
4.3.1 多对一模型 116
4.3.2 一对一模型 116
4.3.3 多对多模型 116
4.4 线程库 117
4.4.1 Pthreads 118
4.4.2 Windows线程 119
4.4.3 Java线程 121
4.5 隐式多线程 122
4.5.1 线程池 123
4.5.2 OpenMP 124
4.5.3 大中央调度 125
4.5.4 其他方法 125
4.6 多线程问题 125
4.6.1 系统调用fork()和exec() 125
4.6.2 信号处理 126
4.6.3 线程撤销 127
4.6.4 线程本地存储 128
4.6.5 调度程序激活 128
4.7 操作系统例子 129
4.7.1 Windows线程 129
4.7.2 Linux线程 130
4.8 小结 131
习题 131
编程题 133
编程项目 134
推荐读物 136
参考文献 136
第5章 进程调度 138
5.1 基本概念 138
5.1.1 CPU-I/O执行周期 138
5.1.2 CPU调度程序 139
5.1.3 抢占调度 139
5.1.4 调度程序 140
5.2 调度准则 140
5.3 调度算法 141
5.3.1 先到先服务调度 141
5.3.2 最短作业优先调度 142
5.3.3 优先级调度 144
5.3.4 轮转调度 145
5.3.5 多级队列调度 147
5.3.6 多级反馈队列调度 148
5.4 线程调度 149
5.4.1 竞争范围 149
5.4.2 Pthreads调度 149
5.5 多处理器调度 151
5.5.1 多处理器调度的方法 151
5.5.2 处理器亲和性 151
5.5.3 负载平衡 152
5.5.4 多核处理器 152
5.6 实时CPU调度 154
5.6.1 最小化延迟 154
5.6.2 优先权调度 155
5.6.3 单调速率调度 156
5.6.4 最早截止期限优先调度 157
5.6.5 比例分享调度 158
5.6.6 POSIX实时调度 158
5.7 操作系统例子 160
5.7.1 例子:Linux调度 160
5.7.2 例子:Windows调度 162
5.7.3 例子:Solaris调度 164
5.8 算法评估 165
5.8.1 确定性模型 166
5.8.2 排队模型 167
5.8.3 仿真 167
5.8.4 实现 168
5.9 小结 169
习题 170
推荐读物 172
参考文献 173
第6章 同步 175
6.1 背景 175
6.2 临界区问题 177
6.3 Peterson解决方案 178
6.4 硬件同步 179
6.5 互斥锁 181
6.6 信号量 181
6.6.1 信号量的使用 182
6.6.2 信号量的实现 182
6.6.3 死锁与饥饿 184
6.6.4 优先级的反转 184
6.7 经典同步问题 185
6.7.1 有界缓冲问题 185
6.7.2 读者-作者问题 186
6.7.3 哲学家就餐问题 187
6.8 管程 188
6.8.1 使用方法 189
6.8.2 哲学家就餐问题的管程解决方案 190
6.8.3 采用信号量的管程实现 191
6.8.4 管程内的进程重启 192
6.9 同步例子 193
6.9.1 Windows同步 193
6.9.2 Linux同步 194
6.9.3 Solaris同步 195
6.9.4 Pthreads同步 196
6.10 替代方法 197
6.10.1 事务内存 198
6.10.2 OpenMP 199
6.10.3 函数式编程语言 199
6.11 小结 200
习题 200
编程题 204
编程项目 205
推荐读物 209
参考文献 210
第7章 死锁 212
7.1 系统模型 212
7.2 死锁特征 213
7.2.1 必要条件 214
7.2.2 资源分配图 215
7.3 死锁处理方法 216
7.4 死锁预防 217
7.4.1 互斥 217
7.4.2 持有且等待 217
7.4.3 无抢占 218
7.4.4 循环等待 218
7.5 死锁避免 220
7.5.1 安全状态 220
7.5.2 资源分配图算法 221
7.5.3 银行家算法 222
7.6 死锁检测 224
7.6.1 每种资源类型只有单个实例 224
7.6.2 每种资源类型可有多个实例 225
7.6.3 应用检测算法 226
7.7 死锁恢复 227
7.7.1 进程终止 227
7.7.2 资源抢占 227
7.8 小结 228
习题 228
编程题 230
编程项目 230
推荐读物 231
参考文献 232
第三部分 内存管理 234
第8章 内存管理策略 234
8.1 背景 234
8.1.1 基本硬件 234
8.1.2 地址绑定 236
8.1.3 逻辑地址空间与物理地址空间 236
8.1.4 动态加载 237
8.1.5 动态链接与共享库 238
8.2 交换 238
8.2.1 标准交换 238
8.2.2 移动系统的交换 239
8.3 连续内存分配 240
8.3.1 内存保护 240
8.3.2 内存分配 241
8.3.3 碎片 242
8.4 分段 242
8.4.1 基本方法 243
8.4.2 分段硬件 243
8.5 分页 244
8.5.1 基本方法 245
8.5.2 硬件支持 247
8.5.3 保护 250
8.5.4 共享页 251
8.6 页表结构 252
8.6.1 分层分页 252
8.6.2 哈希页表 254
8.6.3 倒置页表 254
8.6.4 Oracle SPARC Solaris 255
8.7 例子:Intel 32位与64位体系结构 256
8.7.1 IA-32架构 256
8.7.2 x86-64 258
8.8 例子:ARM架构 259
8.9 小结 259
习题 260
编程题 262
推荐读物 262
参考文献 263
第9章 虚拟内存管理 264
9.1 背景 264
9.2 请求调页 266
9.2.1 基本概念 266
9.2.2 请求调页的性能 269
9.3 写时复制 271
9.4 页面置换 272
9.4.1 基本页面置换 273
9.4.2 FIFO 页面置换 275
9.4.3 最优页面置换 276
9.4.4 LRU页面置换 276
9.4.5 近似LRU页面置换 278
9.4.6 基于计数的页面置换 279
9.4.7 页面缓冲算法 280
9.4.8 应用程序与页面置换 280
9.5 帧分配 280
9.5.1 帧的最小数 281
9.5.2 分配算法 282
9.5.3 全局分配与局部分配 282
9.5.4 非均匀内存访问 283
9.6 系统抖动 283
9.6.1 系统抖动的原因 284
9.6.2 工作集模型 285
9.6.3 缺页错误频率 286
9.6.4 结束语 287
9.7 内存映射文件 287
9.7.1 基本机制 287
9.7.2 共享内存Windows API 288
9.7.3 内存映射I/O 290
9.8 分配内核内存 291
9.8.1 伙伴系统 291
9.8.2 slab分配 292
9.9 其他注意事项 293
9.9.1 预调页面 293
9.9.2 页面大小 293
9.9.3 TLB范围 294
9.9.4 倒置页表 295
9.9.5 程序结构 295
9.9.6 I/O联锁与页面锁定 296
9.10 操作系统例子 297
9.10.1 Windows 297
9.10.2 Solaris 298
9.11 小结 299
习题 300
编程题 303
编程项目 304
推荐读物 306
参考文献 306
第四部分 存储管理 310
第10章 文件系统 310
10.1 文件概念 310
10.1.1 文件属性 310
10.1.2 文件操作 311
10.1.3 文件类型 315
10.1.4 文件结构 316
10.1.5 内部文件结构 316
10.2 访问方法 316
10.2.1 顺序访问 317
10.2.2 直接访问 317
10.2.3 其他访问方法 318
10.3 目录与磁盘的结构 319
10.3.1 存储结构 319
10.3.2 目录概述 320
10.3.3 单级目录 320
10.3.4 两级目录 321
10.3.5 树形目录 322
10.3.6 无环图目录 323
10.3.7 通用图目录 325
10.4 文件系统安装 326
10.5 文件共享 327
10.5.1 多用户 327
10.5.2 远程文件系统 328
10.5.3 一致性语义 330
10.6 保护 331
10.6.1 访问类型 331
10.6.2 访问控制 331
10.6.3 其他保护方式 333
10.7 小结 334
习题 334
推荐读物 335
参考文献 335
第11章 文件系统实现 337
11.1 文件系统结构 337
11.2 文件系统实现 338
11.2.1 概述 338
11.2.2 分区与安装 341
11.2.3 虚拟文件系统 341
11.3 目录实现 343
11.3.1 线性列表 343
11.3.2 哈希表 343
11.4 分配方法 344
11.4.1 连续分配 344
11.4.2 链接分配 345
11.4.3 索引分配 347
11.4.4 性能 348
11.5 空闲空间管理 349
11.5.1 位向量 349
11.5.2 链表 350
11.5.3 组 350
11.5.4 计数 350
11.5.5 空间图 351
11.6 效率与性能 351
11.6.1 效率 351
11.6.2 性能 352
11.7 恢复 354
11.7.1 一致性检查 354
11.7.2 基于日志的文件系统 354
11.7.3 其他解决方法 355
11.7.4 备份和恢复 356
11.8 NFS 356
11.8.1 概述 357
11.8.2 安装协议 358
11.8.3 NFS协议 358
11.8.4 路径名称转换 359
11.8.5 远程操作 360
11.9 例子:WAFL文件系统 360
11.10 小结 362
习题 363
编程题 364
推荐读物 365
参考文献 365
第12章 大容量存储结构 367
12.1 大容量存储结构概述 367
12.1.1 磁盘 367
12.1.2 固态磁盘 368
12.1.3 磁带 368
12.2 磁盘结构 369
12.3 磁盘连接 369
12.3.1 主机连接存储 369
12.3.2 网络连接存储 370
12.3.3 存储区域网络 370
12.4 磁盘调度 371
12.4.1 FCFS调度 371
12.4.2 SSTF调度 371
12.4.3 SCAN调度 372
12.4.4 C-SCAN调度 373
12.4.5 LOOK调度 373
12.4.6 磁盘调度算法的选择 373
12.5 磁盘管理 374
12.5.1 磁盘格式化 374
12.5.2 引导块 375
12.5.3 坏块 376
12.6 交换空间管理 377
12.6.1 交换空间的使用 377
12.6.2 交换空间位置 377
12.6.3 交换空间管理:例子 378
12.7 RAID结构 378
12.7.1 通过冗余提高可靠性 379
12.7.2 通过并行处理提高性能 380
12.7.3 RAID级别 380
12.7.4 RAID级别的选择 383
12.7.5 扩展 384
12.7.6 RAID的问题 384
12.8 稳定存储实现 385
12.9 小结 386
习题 387
编程题 388
推荐读物 388
参考文献 389
第13章 I/O系统 390
13.1 概述 390
13.2 I/O硬件 390
13.2.1 轮询 392
13.2.2 中断 393
13.2.3 直接内存访问 396
13.2.4 I/O硬件小结 397
13.3 应用程序I/O接口 397
13.3.1 块与字符设备 399
13.3.2 网络设备 400
13.3.3 时钟与定时器 400
13.3.4 非阻塞与异步I/O 401
13.3.5 向量I/O 402
13.4 内核I/O子系统 402
13.4.1 I/O调度 402
13.4.2 缓冲 403
13.4.3 缓存 404
13.4.4 假脱机与设备预留 405
13.4.5 错误处理 405
13.4.6 I/O保护 405
13.4.7 内核数据结构 406
13.4.8 内核I/O子系统小结 406
13.5 I/O请求转成硬件操作 407
13.6 流 409
13.7 性能 410
13.8 小结 412
习题 413
推荐读物 414
参考文献 414
第五部分 保护与安全 416
第14章 系统保护 416
14.1 保护目标 416
14.2 保护原则 417
14.3 保护域 417
14.3.1 域结构 418
14.3.2 例子:UNIX 419
14.3.3 例子:MULTICS 420
14.4 访问矩阵 421
14.5 访问矩阵的实现 423
14.5.1 全局表 423
14.5.2 对象的访问列表 423
14.5.3 域的能力列表 424
14.5.4 锁-钥匙机制 424
14.5.5 比较 424
14.6 访问控制 425
14.7 访问权限的撤回 426
14.8 基于能力的系统 427
14.8.1 例子:Hydra 427
14.8.2 例子:剑桥CAP系统 428
14.9 基于语言的保护 428
14.9.1 基于编译程序的实现 429
14.9.2 Java的保护 430
14.10 小结 432
习题 432
推荐读物 433
参考文献 433
第15章 系统安全 436
15.1 安全问题 436
15.2 程序威胁 438
15.2.1 特洛伊木马 438
15.2.2 后门 439
15.2.3 逻辑炸弹 440
15.2.4 堆栈和缓冲区溢出 440
15.2.5 病毒 442
15.3 系统和网络的威胁 444
15.3.1 蠕虫 445
15.3.2 端口扫描 447
15.3.3 拒绝服务 448
15.4 作为安全工具的密码术 448
15.4.1 加密 449
15.4.2 密码术的实现 454
15.4.3 例子:SSL 454
15.5 用户认证 456
15.5.1 密码 456
15.5.2 密码漏洞 456
15.5.3 密码安全 457
15.5.4 一次性密码 458
15.5.5 生物识别技术 458
15.6 实现安全防御 459
15.6.1 安全策略 459
15.6.2 漏洞评估 459
15.6.3 入侵检测 460
15.6.4 病毒防护 462
15.6.5 审计、记账和日志 464
15.7 保护系统和网络的防火墙 464
15.8 计算机安全等级 465
15.9 例子:Windows 7 466
15.10 小结 468
习题 468
推荐读物 469
参考文献 470
第六部分 案例研究 474
第16章 Linux系统 474
16.1 Linux历史 474
16.1.1 Linux内核 475
16.1.2 Linux系统 476
16.1.3 Linux发行 476
16.1.4 Linux许可 477
16.2 设计原则 477
16.3 内核模块 479
16.3.1 模块管理 480
16.3.2 驱动程序注册 480
16.3.3 冲突解决 481
16.4 进程管理 481
16.4.1 fork()/exec()进程模型 481
16.4.2 进程与线程 483
16.5 调度 484
16.5.1 进程调度 484
16.5.2 实时调度 485
16.5.3 内核同步 486
16.5.4 对称多处理 487
16.6 内存管理 488
16.6.1 物理内存管理 488
16.6.2 虚拟内存 490
16.6.3 执行与加载用户程序 492
16.7 文件系统 494
16.7.1 虚拟文件系统 494
16.7.2 Linux ext3文件系统 495
16.7.3 日志 497
16.7.4 Linux进程文件系统 497
16.8 输入与输出 498
16.8.1 块设备 499
16.8.2 字符设备 500
16.9 进程间通信 500
16.9.1 同步与信号 500
16.9.2 进程间的数据传递 501
16.10 网络结构 501
16.11 安全 503
16.11.1 认证 503
16.11.2 访问控制 503
16.12 小结 504
习题 505
推荐读物 506
参考文献 506
第17章 Windows 7 507
17.1 历史 507
17.2 设计原则 509
17.2.1 安全性 509
17.2.2 可靠性 509
17.2.3 Windows和POSIX应用程序兼容性 510
17.2.4 高性能 511
17.2.5 可扩展性 512
17.2.6 可移植性 512
17.2.7 国际化支持 513
17.2.8 电源效率 513
17.2.9 动态设备支持 513
17.3 系统组件 513
17.3.1 硬件抽象层 514
17.3.2 内核 514
17.3.3 执行体 518
17.4 终端服务与快速用户切换 531
17.5 文件系统 532
17.5.1 NTFS内部布局 532
17.5.2 恢复 534
17.5.3 安全 535
17.5.4 卷管理和容错 535
17.5.5 压缩 536
17.5.6 安装点、符号链接和硬链接 536
17.5.7 变更日志 537
17.5.8 卷的影子副本 537
17.6 网络 537
17.6.1 网络接口 537
17.6.2 协议 537
17.6.3 重定向器与服务器 539
17.6.4 域 540
17.6.5 活动目录 540
17.7 程序员接口 540
17.7.1 访问内核对象 541
17.7.2 进程间共享对象 541
17.7.3 进程管理 542
17.7.4 使用Windows消息传递的进程间通信 545
17.7.5 内存管理 546
17.8 小结 547
习题 548
推荐读物 548
参考文献 549
第18章 有影响的操作系统 550
18.1 特征迁移 550
18.2 早期系统 551
18.2.1 专用计算机系统 551
18.2.2 共享计算机系统 552
18.2.3 重叠I/O 554
18.3 Atlas 555
18.4 XDS-940 556
18.5 THE 556
18.6 RC 4000 557
18.7 CTSS 558
18.8 MULTICS 558
18.9 IBM OS/360 558
18.10 TOPS-20 559
18.11 CP/M与MS/DOS 560
18.12 Macintosh OS与Windows 560
18.13 Mach 561
18.14 其他系统 562
习题 562
推荐读物 562
参考文献 563
索引 565