第1章 简介 1
1.1 简介 1
1.1.1 简史 1
1.1.2 创始之初 1
1.1.3 繁衍 2
1.1.4 BSD 3
1.1.5 System V 4
1.1.6 商业化 4
1.1.8 标准 5
1.1.7 Mach 5
1.1.9 OSF和UI 6
1.1.10 SVR4及其之后 7
1.2 演变的动力 7
1.2.1 功能 7
1.2.2 网络 8
1.2.3 性能 8
1.2.4 硬件变化 9
1.2.5 改进质量 9
1.2.6 模式变化 9
1.2.8 简洁就是美 10
1.2.7 其他应用领域 10
1.2.9 灵活性 11
1.3 回顾与展望 12
1.3.1 UNIX好在哪里 12
1.3.2 UNIX的误区在哪儿 13
1.4 本书的范围 14
1.5 参考文献 15
第2章 进程与内核 17
2.1 简介 17
2.2 模式,空间和上下文 19
2.3 进程抽象 20
2.3.1 进程状态 21
2.3.2 进程上下文 22
2.3.3 用户凭证 23
2.3.4 u区和proc结构 24
2.4 内核态下运行 25
2.4.1 系统调用接口 26
2.4.2 中断处理 27
2.5 同步 29
2.5.2 中断 30
2.5.1 阻塞操作 30
2.5.3 多处理器 32
2.6 进程调度 32
2.7 信号 33
2.8 新进程和程序 33
2.8.1 fork和exec 34
2.8.2 进程创建 35
2.8.3 fork 优化 35
2.8.4 执行一个新程序 36
2.8.5 进程终止 37
2.8.6 等待进程终止 38
2.8.7 僵尸(Zombie)进程 39
2.9 小结 39
2.10 练习 39
2.11 参考文献 40
第3章 线程和轻量级进程 41
3.1 简介 41
3.1.1 动机 41
3.1.2 多线程和多处理器 42
3.2 基本抽象概念 44
3.1.3 并发和并行 44
3.2.1 内核线程 45
3.2.2 轻量级进程 45
3.2.3 用户线程 47
3.3 轻量级进程设计——要考虑的问题 50
3.3.1 fork的语义 50
3.3.2 其他的系统调用 51
3.3.3 信号传递和处理 51
3.3.4 可视性 52
3.3.5 堆栈增长 52
3.4.2 线程库的实现 53
3.4 用户级线程库 53
3.4.1 编程接口 53
3.5 调度器调用 54
3.6 Solaris和SVR4的多线程处理 55
3.6.1 内核线程 56
3.6.2 轻量级进程的实现 56
3.6.3 用户线程 57
3.6.4 用户线程的实现 58
3.6.5 中断处理 59
3.6.6 系统调用处理 59
3.7.1 Mach的抽象概念——任务和线程 60
3.7 Mach中的线程 60
3.7.2 Mach的C-threads 61
3.8 Digital UNIX 62
3.8.1 UNIX接口 62
3.8.2 系统调用和信号 64
3.8.3 pthreads线程库 64
3.9 Mach 3.0的续体 65
3.9.1 编程模型 65
3.9.2 使用续体 66
3.9.3 优化 67
3.9.4 分析 68
3.10 小结 68
3.11 练习 68
3.12 参考文献 69
第4章 信号和会话管理 72
4.1 简介 72
4.2 信号生成和处理 72
4.2.1 信号处理 73
4.2.2 信号生成 75
4.2.4 睡眠和信号 76
4.2.3 曲型情景 76
4.3 不可靠信号 77
4.4 可靠的信号 78
4.4.1 主要特性 78
4.4.2 SVR3的实现 79
4.4.3 BSD信号管理 80
4.5 SVR4信号机制 81
4.6 信号机制的实现 82
4.6.1 信号生成 82
4.7 异常 83
4.6.2 信号传递和处理 83
4.8 Mach中的异常处理 84
4.8.1 异常端口 84
4.8.2 错误处理 85
4.8.3 调试器的交互 86
4.8.4 分析 86
4.9 进程组和终端管理 87
4.9.1 基本概念 87
4.9.2 SVR3模型 87
4.9.3 局限性 89
4.9.4 4.3 BSD中的进程组和终端 89
4.10 SVR4会话的体系结构 91
4.9.5 缺点 91
4.10.2 会话和进程组 92
4.10.1 目的(动机) 92
4.10.3 数据结构 93
4.10.4 控制终端 94
4.10.5 4.4 BSD中会话的实现 95
4.11 小结 95
4.12 练习 95
4.13 参考文献 97
5.1 简介 98
第5章 进程调度 98
5.2 时钟中断处理 99
5.2.1 调出莲表 99
5.2.2 报警 101
5.3 调度器的目标 101
5.4 传统的UNIX调度 102
5.4.1 进程优先级 103
5.4.2 调度器的实现 104
5.4.3 运行队列管理 105
5.5 SVR4的调度器 106
5.4.4 分析 106
5.5.1 类无关层 107
5.5.2 调度类的接口 108
5.5.3 分时类 110
5.5.4 实时类 111
5.5.5 系统调用priocntl 112
5.5.6 分析 113
5.6 Solaris2.x调度的改善 114
5.6.1 抢占式内核 114
5.6.2 多处理器的支持 114
5.6.3 隐式调度 115
5.6.4 优先级逆转 116
5.6.5 优先级继承的实现 118
5.6.6 优先继承的局限性 120
5.6.7 Turnstiles 120
5.6.8 分析 121
5.7 mach中的调度 121
5.7.1 多处理器的支持 122
5.8 Digital UNIX的实时调度器 124
5.8.1 多处理器支持 124
5.9.2 最终期限驱动调度 125
5.9 其他的一些调度实现 125
5.9.1 fair share调度 125
5.9.3 三级(Three-Level)调度器 126
5.10 小结 127
5.11 练习 127
5.12 参考文献 128
第6章 进程间通信 130
6.1 简介 130
6.2 通用IPC方法 130
6.2.2 管道 131
6.2.1 信号 131
6.2.3 SVR4的管道 133
6.2.4 进程跟踪 133
6.3 System V的进程间通信 135
6.3.1 公共元素 135
6.3.2 信号量 136
6.3.3 消息队列 139
6.3.4 共享内存 141
6.3.5 讨论 143
6.4 Mach IPC 143
6.4.1 基本概念 144
6.5 消息 145
6.5.1消息的数据结构 146
6.5.2 消息传递接口 147
6.6 端口 148
6.6.1端口名字空间 148
6.6.2 端口数据结构 148
6.6.3 端口变换 149
6.7 消息传递 149
6.7.1 端口权力的传递 150
6.7.2 脱机内存 152
6.7.4 通知 154
6.7.3 控制流 154
6.8 端口操作 155
6.8.1 释放一个端口 155
6.8.2 备份端口 155
6.8.3 端口集合 155
6.8.4 端口的添加 157
6.9 扩展性 158
6.10 Mach 3.0的改进 159
6.10.1 一次发送权 159
6.11 讨论 160
6.10.2 Mach 3.0的通知 160
6.10.3 发送权的用户引用记数 160
6.12 小结 161
6.13 练习 161
6.14 参考文献 162
第7章 同步和多处理器 164
7.1 简介 164
7.2 传统UNIX内核中的同步 165
7.2.1 中断屏蔽 165
7.2.2 睡眠和唤醒 165
7.2.3 传统方法的局限性 166
7.3 多处理器系统 167
7.3.1 内存模型 167
7.3.2 同步支持 169
7.3.3 软件体系结构 170
7.4 多处理器同步问题 170
7.4.1 唤醒丢失问题 171
7.4.2 巨群问题 171
7.5 信号灯 172
7.5.3 用于控制可计数资源的信号灯 173
7.5.2 使用的信号灯的事件等待 173
7.5.1 提供互斥访问的信号灯 173
7.5.4 信号灯的缺点 174
7.5.5 护卫 174
7.6 自旋锁 175
7.6.1 自旋锁的使用 176
7.7 条件变量 176
7.7.1 实现问题 178
7.7.2 事件 178
7.8.1 设计考虑 179
7.8 读写锁 179
7.7.3 阻塞锁 179
7.8.2 实现 180
7.9 引用计数 181
7.10 其他考虑 182
7.10.1 死锁避免 182
7.10.2 递归锁 183
7.10.3 阻塞还是自旋 184
7.10.4 锁什么 184
7.10.5 粒度和持续时间 184
7.11.1 SVR4.2/MP 185
7.11 例子分析 185
7.11.2 Digital UNIX 186
7.11.3 其他实现 187
7.12 小结 188
7.13 练习 188
7.14 参考文献 189
第8章 文件系统接口和框架 191
8.1 简介 191
8.2 文件的用户接口 191
8.2.1 文件和目录 192
8.2.2 文件属性 193
8.2.3 文件描述符 195
8.2.4 文件I/O 197
8.2.5 分散-聚集I/O(Scatter-Gather I/O) 197
8.2.6 文件加锁 198
8.3 文件系统 199
8.3.1 逻辑磁盘 200
8.4 特殊文件 200
8.4.1 符号链接 200
8.5 文件系统框架 202
8.4.2 管道和FIFO 202
8.6 vnode/vfs体系结构 203
8.6.1 目标 203
8.6.2 设备I/O的经验 204
8.6.3 vnode/vfs接口概述 206
8.7 实现概述 207
8.7.1 目标 207
8.7.2 v节点和打开文件 208
8.7.3 v节点 209
8.7.4 v节点引用计数 210
8.7.5 vfs对象 211
8.8 文件系统相关对象 212
8.8.1 每个文件的私有数据 212
8.8.2 vnodeops向量 213
8.8.3 vfs层中的文件系统相关部分 214
8.9 安装一个文件系统 214
8.9.1 虚拟文件系统转换 215
8.9.2 mount的实现 215
8.9.3 VFS-MOUNT处理 216
8.10 对文件的操作 216
8.10.1 路径名遍历 216
8.10.2 目录查找缓存 217
8.10.3 VOP_LOOKUP操作 218
8.10.4 打开文件 219
8.10.5 文件I/O 219
8.10.6 文件属性 220
8.10.7 用户凭证 220
8.11 分析 220
8.11.1SVR4实现的缺点 221
8.11.2 4.4BSD模型 222
8.12 小结 223
8.11.3 OSF/1方法 223
8.13 练习 224
8.14 参考文献 225
第9章 文件系统实现 227
9.1 简介 227
9.2 System V文件系统(s5fs) 228
9.2.1 目录 228
9.2.2 i节点 229
9.2.3 超级块 231
9.3.1 内存i节点 232
9.3 s5fs内核组织 232
9.3.2 i节点查找 233
9.3.3 文件I/O 233
9.3.4 i节点的分配与回收 234
9.4 对s5fs的分析 236
9.5 伯克利快速文件系统(FFS) 236
9.6 硬盘结构 237
9.7 磁盘组织 238
9.7.1 块和碎片 238
9.7.2 分配策略 239
9.8 FFS的增强功能 240
9.9 分析 241
9.10 临时文件系统 242
9.10.1 内存文件系统 243
9.10.2 tmpfs文件系统 243
9.11 特殊目的文件系统 244
9.11.1 specfs文件系统 244
9.11.2 /proc文件系统 245
9.11.3 处理器文件系统 246
9.11.4 半透明文件系统 247
9.12.1 基本操作 248
9.12 以往的磁盘缓存 248
9.12.3 优点 249
9.12.2 缓冲区头结构 249
9.12.4 缺点 250
9.12.5 保证文件系统的一致性 250
9.13 小结 251
9.14 练习 251
9.15 参考文献 252
10.1 简介 255
10.2 分布式文件系统的一般特征 255
第10章 分布式文件系统 255
10.2.1 设计考虑 256
10.3 网络文件系统(NFS) 256
10.3.1 用户透视 257
10.3.2 设计目标 258
10.3.3 NFS组成 258
10.3.4 无状态 260
10.4 协议族 261
10.4.1 扩展数据表示(XDR) 261
10.4.2 远程过程调用(RPC) 262
10.5.1 控制流 264
10.5 NFS实现 264
10.5.2 文件句柄 265
10.5.3 Mount操作 265
10.5.4 路径名查找 266
10.6 UNIX语义 266
10.6.1 打开文件权限 266
10.6.2 删除打开文件 267
10.6.3 读和写 267
10.7.3 延迟写 268
10.7.2 客户端高速缓存 268
10.7.1 性能瓶颈 268
10.7 NFS性能 268
10.7.4 重传高速缓存 269
10.8 专用NFS服务器 271
10.8.1 Auspex功能性多处理器结构 271
10.8.2 IBM的HA-NFS服务器 272
10.9 NFS安全性 273
10.9.1 NFS访问控制 273
10.9.2 UID重新映射 274
10.9.3 root重新映射 274
10.10 NFSv3 275
10.11 远程文件共享(RFS)文件系统 276
10.12 RFS结构 276
10.12.1 远程消息协议 277
10.12.2 有状态操作 278
10.13 RFS实现 278
10.13.1 远程安装 278
10.13.2 RFS客户和服务器 280
10.13.3 崩溃恢复 280
10.14 客户端高速缓存 281
10.13.4 其他问题 281
10.14.1 高速缓存一致性 282
10.15 Andrew文件系统 283
10.15.1 可扩展的结构 284
10.15.2 存储和名字空间组织 284
10.15.3 会话语义 285
10.16 AFS实现 286
10.16.1 缓存以及一致性 286
10.16.2 路径名查找 287
10.16.3 安全性 287
10.18 DCE分布式文件系统(DCE DFS) 288
10.17 AFS的缺陷 288
10.18.1 DFS体系结构 289
10.18.2 高速缓冲区一致性 289
10.18.3 令牌管理器 291
10.18.4 其他DFS服务 291
10.18.5 分析 292
10.19 小结 292
10.20 练习 293
10.21 参考文献 294
11.2 传统文件系统的局限 298
11.1 简介 298
第11章 高级文件系统 298
11.2.1 FFS磁盘布局 299
11.2.2 写的主导性 300
11.2.3 元数据更新 301
11.2.4 崩溃恢复 301
11.3 文件系统成簇(Sun-FFS) 302
11.4 日志方法 303
11.4.1 基本特征 303
11.5 日志结构文件系统 304
11.6 4.4BSD日志文件系统 305
11.6.1 写日志 306
11.6.2 数据检索 306
11.6.3 崩溃恢复 307
11.6.4 清除进程 307
11.6.5 分析 308
11.7 元数据日志 309
11.7.1 正常操作 309
11.7.2 日志的一致性 310
11.7.4 分析 312
11.7.3 崩溃恢复 312
11.8 Episode文件系统 313
11.8.1 基本抽象 313
11.8.2 结构 314
11.8.3 记日志 315
11.8.4 其他特性 315
11.9 监视器(watchdog) 316
11.9.1 目录监视器 317
11.9.2 消息通道 317
11.9.3 应用 318
11.10.1 使用端口(portals) 319
11.10 4.4BSD端口文件系统 319
11.11 堆栈式文件系统层 320
11.11.1 框架和接口 321
11.11.2 Sun Soft原型 322
11.12 4.4BSD文件系统接口 323
11.12.1 Nullfs和Union Mount文件系统 324
11.13 小结 324
11.14 练习 324
11.15 参考文献 325
12.1 简介 328
第12章 内核内存管理 328
12.2 功能需求 329
12.2.1 评估标准 330
12.3 资源映射图分配器 331
12.3.1 分析 332
12.4 简单2次幂空闲表 333
12.4.1 分析 334
12.5 McKusick-Karels分配器 335
12.5.1 分析 336
12.6 伙伴系统 337
12.7.1 Lazy合并 339
12.6.1 分析 339
12.7 SVR4 Lazy伙伴算法 339
12.7.2 SVR4实现细节 340
12.8 Mach-OSF/1的Zone分配器 341
12.8.1 垃圾收集 341
12.8.2 分析 342
12.9 多处理器的分层分配器 343
12.9.1 分析 344
12.10.1 对象复用 345
12.10.2 硬件Cache利用率 345
12.10 Solaris2.4的Slab分配器 345
12.10.3 分配器footprint 346
12.10.4 设计与接口 346
12.10.5 实现 347
12.10.6 分析 348
12.11 小结 349
12.12 练习 349
12.13 参考文献 350
第13章 虚存 352
13.1 简介 352
13.1.1内存管理的石器时代 353
13.2 分页 355
13.2.1功能需求 355
13.2.2 虚拟地址空间 356
13.2.3 页面初始访问 357
13.2.4 交换区 357
13.2.5 转换映射图 358
13.2.6 页面替换策略 359
13.3 硬件需求 360
13.3.1 MMU缓存 361
13.3.2 Intel 80x86 362
13.3.3 IBM RS/6000 364
13.3.4 MIPS R3000 367
13.4 4.3BSD实例研究 368
13.4.1 物理内存 369
13.4.2 地址空间 370
13.4.3 页面在哪里 371
13.4.4 交换区 372
13.5 4.3BSD内存管理操作 373
13.5.1 创建进程 373
13.5.2 页面失效处理 375
13.5.3 空闲页面链表 376
13.5.4 交换 377
13.6 分析 379
13.7练习 380
13.8 参考文献 380
第14章 SVR4 VM体系结构 382
14.1 动机 382
14.2 内存映射文件 382
14.2.1 mmap及相关系统调382用 384
14.3 VM设计原理 385
14.4 基本抽象概念 385
14.4.1 物理内存 386
14.4.2 地址空间 387
14.4.3 地址映射 388
14.4.4 匿名页面 389
14.4.5 硬件地址转换 390
14.5 段驱动程序 391
14.5.1 seg-vn 391
14.5.2 seg-map 392
14.5.3 seg-dev 393
14.5.4 seg-kmem 393
14.5.5 seg kp 393
14.6 交换层 393
14.7 VM操作 395
14.7.1 创建一个新映射 395
14.7.2 匿名页面处理 396
14.7.3 创建进程 397
14.7.4 共享匿名页面 397
14.7.5 页面失效处理 399
14.7.6 共享内存 400
14.7.7 其他部件 400
14.8 与v节点子系统的交互 401
14.8.1 v节点接口变化 402
14.8.2 统一的文件访问 402
14.8.3 其他问题 404
14.9 Solaris中的虚拟交换空间 405
14.9.1 扩展交换空间 405
14.9.2 虚交换管理 405
14.10 分析 407
14.9.3 讨论 407
14.11 性能改进 409
14.11.1 高失效率原因 409
14.11.2 SVR4对SunOS VM实现的改进 410
14.11.3 结果与讨论 410
14.12 小结 411
14.13 练习 411
14.14 参考文献 412
15.2.1 设计目标 413
15.2 Mach的内存管理设计 413
15.1 简介 413
第15章 进一步关于内存管理的主题 413
15.2.2 编程接口 414
15.2.3 基本抽象概念 415
15.3 共享内存设施 417
15.3.1 copy-on-write共享 417
15.3.2 读写共享 418
15.4 内存对象和Pager 419
15.4.1 内存对象初始化 419
15.4.2 内核与Pager间的接口 421
15.5 外部Pager和内部Pager 422
15.4.3 内核与Pager交互 422
15.5.1 一个网络共享内存服务器 423
15.6 页面替换 425
15.7 分析 426
15.8 4.4BSD的内存管理 427
15.9 快表(TLB)一致性 429
15.9.1 单处理机上的TLB一致性 430
15.9.2 多处理机问题 430
15.10 Mach的TLB击落算法 431
15.10.1 同步和死锁避免 432
15.11 SVR4和SVR4.2 UNIX中的TLB一致性 433
15.10.2 讨论 433
15.11.1 SVR4/MP 434
15.11.2 SVR4.2/MP 434
15.11.3 Lazy击落算法 435
15.11.4 立即击落 435
15.11.5 讨论 437
15.12 其他TLB一致性算法 437
15.13 虚地址缓存 438
15.13.1 映射变化 439
15.13.3 DMA操作 440
15.13.2 地址别名 440
15.13.4 维护缓存一致性 441
15.13.5 分析 442
15.14 练习 442
15.15 参考文献 443
第16章 设备驱动程序I/O 446
16.1 简介 446
16.2 概述 446
16.2.1硬件配置 447
16.2.2 设备中断 449
16.3 设备驱动程序框架 450
16.3.1 设备和驱动程序分类 450
16.3.2 调用驱动程序代码 451
16.3.3 设备开关表 451
16.3.4 驱动程序入口点 453
16.4 I/O子系统 454
16.4.1 主、次设备号 454
16.4.2 设备文件 455
16.4.3 specfs文件系统 456
16.4.4 公共snode 457
16.4.5 设备克隆 458
16.4.6 字符设备I/O 459
16.5 poll系统调用 460
16.5.1 poll的实现 460
16.5.2 4.3BSD select系统调用 462
16.6 块I/O 462
16.6.1 buf结构 463
16.6.2 与v节点的交互 464
16.6.3 设备访问方法 465
16.6.4 到块设备的raw I/O 466
16.7 DDI/DKI说明 467
16.7.1 建议 468
16.7.2 第三部分函数 469
16.7.3 其他部分 469
16.8 新的SVR4版本 470
16.8.1 多处理器可靠驱动程序 471
16.8.2 SVR4.1/ES的变化 471
16.8.3 动态加载和卸载 472
16.9 发展趋势 474
16.10 小结 475
16.11 练习 475
16.12 参考文献 476
17.1 目的 477
17.2 概述 477
第17章 流 477
17.3 消息和队列 479
17.3.1 消息 480
17.3.2 虚拟拷贝 481
17.3.3 消息类型 482
17.3.4 队列和模块 483
17.4 流I/O 485
17.4.3 流量控制 486
17.4.1 STREAMS调度程序 486
17.4.2 优先带(Priority Bands) 486
17.4.4 驱动程序尾 488
17.4.5 流头 488
17.5 配置和设置 489
17.5.1 配置一个模块或驱动程序 489
17.5.2 打开流 491
17.5.3 插入(Pushing)模块 492
17.5.4 克隆设备 493
17.6 STREAMS ioctl 493
17.6.1 I STR ioctl处理 494
17.6.2 透明ioctl 495
17.7 内存分配 495
17.7.1 扩展STREAMS缓冲区 496
17.8 多路复用 497
17.8.1 上部多路复用器 498
17.8.2 下部多路复用器 498
17.8.3 链接流 499
17.8.4 数据流 500
17.9.1 STREAMS FIFO 501
17.9 FIFO和管道 501
17.8.5 普通链接和持久链接 501
17.9.2 STREAMS管道 502
17.10 网络接口 503
17.10.1 传输供应者接口(TPI) 504
17.10.2 传输层接口(TLI) 504
17.10.3 sockets 505
17.10.4 SVR4 Socket实现 507
17.11 小结 508
17.12 练习 508
17.13 参考文献 509