《操作系统原理·技术与编程》PDF下载

  • 购买积分:16 如何计算积分?
  • 作  者:蒋静,徐志伟著
  • 出 版 社:北京市:机械工业出版社
  • 出版年份:2004
  • ISBN:7111131606
  • 页数:502 页
图书介绍:本书对Linux核心数据结构进行了剖析。

1.1 操作系统的定义 2

1.1.1 计算机系统层次结构图 2

目录 2

第一部分 操作系统初始化 2

第1章 操作系统概述 2

1.1.2 操作系统的定义 3

1.2.1 没有操作系统的第一代计算机 4

1.2 操作系统发展过程中的设计需求分析 4

1.2.2 具有简单批处理操作系统的第二代计算机 5

1.2.3 简单批处理操作系统功能分析 6

1.2.4 多道程序设计的批处理操作系统 7

1.2.6 其他操作系统 8

1.2.5 多道程序设计的分时操作系统 8

1.3.1 大型系统软件分析方法 9

1.3 内核体系结构模型 9

1.3.2 操作系统结构模型 10

1.3.3 UNLX内核系统结构模型 11

1.4 Linux操作系统的出现 12

1.5.1 操作系统运行的全过程 13

1.5 操作系统如何运行一个用户程序 13

1.5.2 客户/服务器工作流程 14

1.5.3 客户/服务器实例 15

1.6.1 重要思想 19

1.6 重要思想和理论 19

1.6.2 重要理论 21

1.7 小结 23

1.9 参考文献 24

1.8 练习题 24

2.1.1 微型计算机基本组成 26

2.1 微型计算机硬件组成 26

第2章 i386硬件与软件接口技术 26

2.1.2 微处理器分类 27

2.1.4 微型计算机总线结构 28

2.1.3 微处理器结构的发展 28

2.2.1 实模式下软件组织 29

2.2 实模式软件结构 29

2.2.3 实模式输入/输出地址空间 31

2.2.2 实模式主存储器地址的产生 31

2.3.1 描述符寄存器 32

2.3 保护模式下存储器管理单元MMU 32

2.3.2 描述符 34

2.3.3 虚拟地址和虚拟地址空间 36

2.3.4 虚实地址转换 37

2.3.5 保护模式指令集 38

2.4.1 多任务与分时系统 39

2.4 保护模式和保护 39

2.4.4 保护性检查 40

2.4.3 保护机制 40

2.4.2 保护环 40

2.4.5 越级访问存储器的代码段和数据段 41

2.5 任务切换机制 43

2.6 小结 44

2.8 参考文献 45

2.7 练习题 45

3.1 BIOS启动过程 46

第3章 Linux系统引导过程 46

3.1.1 i386芯片的启动状态 47

3.1.2 BIOS加载操作系统引导程序 48

3.2.1 软盘引导过程 50

3.2 引导过程 50

3.2.2 硬盘引导过程 53

3.2.3 LILO运行过程分析 55

3.3 实模式下的系统初始化setup()函数 56

3.3.3 准备进入保护模式 57

3.3.2 设置参数 57

3.3.1 setup.S代码签名检查 57

3.3.4 setup.S程序流程图 59

3.3.6 setup.S中全局描述符表分析 63

3.3.5 执行setup.S程序后内存分配图 63

3.4 内核解压缩过程startup_32() 65

3.5 保护模式下的系统初始化startup_32() 67

3.5.2 设置全局描述符表 70

3.5.1 在startup_32中完成临时页表的初始化 70

3.7 练习题 72

3.6 小结 72

3.8 参考文献 73

4.1.1 初始化与体系结构相关的硬件数据结构 74

4.1 初始化系统内核 74

第4章 启动Linux内核 74

4.1.2 解析内核选项 80

4.2 init()函数与init进程 81

4.3.1 继续初始化系统内核 82

4.3 init()函数执行流程 82

4.3.3 init进程 84

4.3.2 系统进程的生成 84

4.4.1 执行脚本文件/etc/rc.d/rc.sysinit 87

4.4 Shell命令文本的执行 87

4.4.2 执行脚本文件/etc/rc.d/rcN.d目录中的各个命令 88

4.5 小结 89

4.4.3 各终端进程的生成 89

4.6 练习题 91

4.7 参考文献 92

5.1.1 多道程序设计与分时共享 94

5.1 并发控制 94

第二部分 并发控制原理及其实现 94

第5章 程序和进程 94

5.1.2 并发控制的硬件支持 95

5.2.1 程序与进程 96

5.2 进程的定义和特征 96

5.2.2 从并发机制理解进程 98

5.3 线程 99

5.2.3 进程的特征 99

5.3.2 内核线程和用户线程 100

5.3.1 多线程 100

5.4 操作系统控制进程的基本方法 101

5.5.1 进程控制块PCB 102

5.5 内核中进程的实现 102

5.5.2 进程状态 104

5.5.3 Linux进程控制块 105

5.5.4 Linux系统O号进程的控制块 107

5.5.5 Linux进程状态 108

5.6 进程的组织 109

5.6.2 pidhash链表 110

5.6.1 进程链表和运行队列链表 110

5.7 内核创建新进程 111

5.6.3 如何寻址当前进程的PCB 111

5.8 Linuxfork的编程实现 112

5.8.1 内核函数do_fork 113

5.8.2 调用fork()的编程实例 117

5.9.1 运行新程序的do_execve() 118

5.9 Linuxexee的编程实现 118

5.8.3 内核怎样运行一个新程序 118

5.9.3 使用fork_exec组合的编程实例 121

5.9.2 二进制处理程序load_binary()完成的工作 121

5.10 从程序到进程 123

5.10.1 文件系统中可执行文件的一般格式 124

5.10.2 shell进程执行用户程序的过程 125

5.12 编程实例——Linux守护进程的编程方法 126

5.11 进程的终止 126

5.12.1 进程组、会话和控制终端 127

5.12.2 Linux守护进程编程细则 129

5.12.3 Linux守护进程实例 131

5.13 小结 132

5.14 练习题 133

5.15 参考文献 134

6.1.1 竞争条件 135

6.1 并发进程控制的基本原理 135

第6章 互斥与同步 135

6.1.2 同步与互斥 136

6.1.3 对互斥操作的要求 137

6.2.1 原子操作 138

6.2 竞争条件产生的原因 138

6.3 基于共享变量的同步操作 139

6.2.2 原子操作的实例 139

6.3.2 锁变量 140

6.3.1 忙等待 140

6.3.3 TestAndSet与Swap指令 141

6.4 信号量 142

6.5.1 DOWN操作 146

6.5 内核使用的P、V操作实例 146

6.5.2 UP操作 149

6.5.5 同步索引节点的信号量 151

6.5.4 同步内存描述符的信号量 151

6.5.3 同步slab高速缓存的信号量 151

6.6.2 关中断 152

6.6.1 内核是不可强占的 152

6.6 内核采用的其他同步技术 152

6.7 等待对列及其操作 153

6.8 小结 155

6.9 练习题 156

6.1 0参考文献 157

7.1.1 可剥夺资源与不可剥夺资源 158

7.1 死锁分析 158

第7章 死锁与饥饿 158

7.1.4 资源分配模型图 159

7.1.3 死锁的条件 159

7.1.2 死锁定义 159

7.3.1 系统资源分配的表示方法 160

7.3 死锁避免 160

7.2 死锁预防 160

7.3.2 系统拒绝启动进程 161

7.3.3 系统拒绝分配资源 162

7.4.1 死锁检测算法 163

7.4 死锁检测和恢复 163

7.4.3 从死锁中恢复 164

7.4.2 死锁检测的时机 164

7.6 饥饿 165

7.5 最简单的死锁策略 165

7.7 小结 166

7.8 练习题 167

7.9 参考文献 168

8.1.1 调度程序的设计目标 169

8.1 进程调度的基本原理 169

第8章 进程调度 169

8.1.2 选择合适的调度策略 170

8.1.3 时间测度指标 171

8.2.1 先来先服务 172

8.2 非强占方式调度算法 172

8.2.2 最短作业优先 173

8.3.1 轮转法 174

8.3 强占式调度算法 174

8.2.3 优先级调度 174

8.3.3 反馈调度算法 175

8.3.2 多级队列 175

8.4.1 在PCB中与调度有关的数据成员 176

8.4 Linux进程调度的实现 176

8.4.2 Linux调度策略 177

8.4.3 Linux调度函数schedule() 179

8.4.4 Linux调度机制 183

8.5 调度程序的编程实例 185

8.6 小结 187

8.7 练习题 188

8.8 参考文献 189

9.1.1 Intel80386芯片的中断接口 190

9.1 基于IBMPC机的中断接口电路 190

第9章 中断技术 190

9.1.2 使用82C59芯片连结外围设备的中断接口电路 191

9.2.1 异常 193

9.2 中断和异常 193

9.2.2 中断和异常的优先级 195

9.3.1 中断和异常向量 196

9.3 中断向量表和中断描述符表 196

9.4 Linux中断系统的初始化过程 197

9.3.2 中断门和陷阱门的区别 197

9.4.2 第二次初始化中断描述符表 198

9.4.1 第一次初始化中断描述符表 198

9.5.1 异常处理过程 200

9.5 异常处理 200

9.5.2 异常处理程序 201

9.6.1 硬件设备使用的中断向量 202

9.6 中断处理 202

9.5.3 内核管理硬件资源的两种异常 202

9.6.2 中断处理使用的数据结构 203

9.6.3 中断系统初始化函数init_IRQ 205

9.6.4 中断处理程序的执行过程 206

9.6.6 执行所有的中断服务例程 208

9.6.5 保存断点现场 208

9.6.7 内核模式的设备驱动程序 209

9.7 下半部分 210

9.7.1 Linux对下半部分的组织 211

9.7.2 执行do_bottom_half()函数 212

9.8 动态安装和释放中断处理程序 213

9.7.3 调度do_bottom_half()函数运行的时机 213

9.9 从中断和异常返回 215

9.10 一个中断处理实例 218

9.10.2 定时器中断的下半部 219

9.10.1 定时器中断的上半部 219

9.10.3 预定义的任务队列 220

9.11 小结 222

9.12 练习题 223

9.13 参考文献 224

10.1 标准C函数库和系统调用 225

第10章 系统调用接口 225

10.2.1 陷阱门处理的模式转换 226

10.2 模式转换的硬件处理 226

10.2.2 调用门处理的模式转换 227

10.3.1 内核对系统调用的初始化 229

10.3 系统调用接口 229

10.3.2 系统调用的执行流程 230

10.3.3 封装例程 231

10.3.4 系统调用号与系统调用表 232

10.3.5 system_call的执行过程 233

10.4 lcall7的执行过程 234

10.5 内核中添加新系统调用的实例 235

10.6 小结 238

10.8 参考文献 239

10.7 练习题 239

11.1 存储器功能需求分析 242

第11章 存储器管理及Linux实现 242

第三部分 OS资源管理及其实现 242

11.1.3 共享 243

11.1.2 保护 243

11.1.1 重定位 243

11.3 内存管理 244

11.2.2 物理组织 244

11.2 存储器的组织方式 244

11.2.1 逻辑组织 244

11.3.1 固定分区 245

11.3.2 动态分区 246

11.4 位图 247

11.5 伙伴系统 248

11.6.2 固定分区使用的重定位技术 250

11.6.1 存储器管理使用的地址类型 250

11.6 重定位技术 250

11.6.3 分页使用的重定位技术 251

11.6.4 分段使用的重定位技术 252

11.7 虚拟存储器管理技术 253

11.7.2 虚拟存储器管理软件 254

11.7.1 局部性原理 254

11.7.3 交换区 256

11.8 通用存储器管理模型 256

11.9 Linux在i386中的分段和分页 257

11.9.1 Linux使用的分段 258

11.9.2 Linux使用的分页 260

11.9.3 Linux在i386平台上定义的页表项格式 261

11.10 Linux内存管理 262

11.10.1 描述内存页框的page数据结构 263

11.10.2 基于buddy算法的内存页框管理 264

11.11 基于slab算法的内存区管理 266

11.11.1 slab分配器的组成 267

11.11.2 slab分配器与页框级分配器的接口和实现 269

11.11.3 连续内存区的分配和释放函数 270

11.12.1 描述非连续内存区的数据结构 271

11.12 非连续内存区的分配和释放 271

11.12.2 分配和释放非连续内存区的函数 272

11.13.1 structmm_struct和structvm_area_struct结构 274

11.13 进程的地址空间 274

11.13.2 进程地址空间的存取权限 276

11.13.3 对线性区进行处理的底层函数 277

11.13.4 进程线性地址空间的映射do_mmap() 279

11.14.1 缺页异常处理程序do_page_fault() 281

11.14 页面失效处理 281

11.13.5 释放进程线性地址空间do_munmap() 281

11.14.2 请求调页 286

11.14.4 调用sys_brk动态增长内存 288

11.14.3 写时拷贝 288

11.15 交换 289

11.15.1 描述交换空间的数据结构 290

11.15.2 页面替换策略 291

11.16.1 页交换守护进程kswapd 292

11.16 页换出操作 292

11.16.2 kswapd()的执行流程 293

11.16.3 页换入do_swap_page() 294

11.16.4 页换出 295

11.18 小结 297

11.17 对交换区数据结构进行操作的函数 297

11.19 练习题 299

11.20 参考文献 300

12.1.2 磁盘的逻辑组织 302

12.1.1 磁盘结构 302

第12章 文件管理及Linux实现 302

12.1 磁盘的物理组织与调度 302

12.1.3 磁盘性能参数 303

12.1.4 磁盘调度算法 304

12.2.1 文件管理的设计目标 305

12.2 文件管理需求分析 305

12.1.5 磁盘纠错 305

12.2.2 文件管理系统结构模型 306

12.3.3 文件属性 307

12.3.2 文件类型和存取方式 307

12.3 文件 307

12.3.1 文件结构 307

12.4.1 目录结构 308

12.4 目录 308

12.5 文件系统的组织 309

12.4.3 目录操作 309

12.4.2 路径名 309

12.5.2 目录表表项的格式 310

12.5.1 文件组织 310

12.5.5 文件系统的一致性 311

12.5.4 磁盘空间管理 311

12.5.3 共享文件 311

12.6 文件系统的保护机制 312

12.7.1 虚拟文件系统的设计思路 313

12.7 虚拟文件系统VFS 313

12.7.2 虚拟文件系统VFS框架 314

12.8.1 VFS超级块数据结构 315

12.8 Linux虚拟文件系统的数据结构 315

12.8.2 VFS的目录项数据结构 317

12.8.3 VFS的inode节点数据结构 319

12.8.4 VFS中数据结构之间的关系 321

12.9.1 文件系统注册链表 322

12.9 对虚拟文件系统的管理 322

12.9.3 根文件系统的安装 323

12.9.2 文件系统安装注册链表 323

12.10.1 安装一个文件系统sys_mount() 325

12.10 对文件系统模块的安装和卸载 325

12.11 进程与文件系统的联系 326

12.10.2 卸载一个文件系统sys_umount() 326

12.11.1 文件对象 327

12.11.2 用户打开文件表 328

12.11.3 根目录和当前工作目录 329

12.12 文件加锁 331

12.13 磁盘数据的内存高速缓冲区 332

12.13.1 缓冲区高速缓存的数据结构 333

12.13.2 buffercache的组织 335

12.13.3 对buffercache的基本操作 337

12.13.4 把脏缓冲区写入磁盘 338

12.14 EXT2文件系统 339

12.14.2 EXT2减少碎片的方案 340

12.14.1 EXT2对物理磁盘的组织 340

12.15 EXT2磁盘重要数据结构 341

12.14.3 EXT2对磁盘块的分配原则 341

12.15.1 EXT2的目录项数据结构 342

12.5.2 EXT2的磁盘i节点结构 343

12.15.3 EXT2磁盘上的超级块 346

12.15.5 EXT2的块位图和索引节点位图 347

12.15.4 EXT2的组描述符 347

12.16.1 EXT2的内存超级块 348

12.16 EXT2的内核组织 348

12.15.6 EXT2存放文件的数据块 348

12.16.3 磁盘i节点读入高速缓存的过程 350

12.16.2 EXT2的内存i节点 350

12.17 如何通过路径名找到索引节点 352

12.18.2 EXT2文件系统的不足 354

12.18.1 关于日志式文件系统 354

12.18 EXT3文件系统 354

12.18.3 日志文件系统的工作原理 355

12.18.4 EXT3日志文件系统的具体实现 356

12.19 小结 357

12.18.5 EXT3文件系统的额外开销 357

12.20 练习题 358

12.21 参考文献 359

13.1.2 内核对设备的分类 360

13.1.1 I/O设备的分类 360

第13章 I/O设备管理与设备驱动程序 360

13.1 I/O系统的基本组成 360

13.1.3 I/O接口功能 361

13.1.4 CPU与I/O设备交互的控制方式 362

13.2 I/O系统管理软件的设计原理 363

13.4.1 设备命名方法 364

13.4 逻辑I/O管理 364

13.3 用户程序 364

13.4.3 为设备分配和释放缓冲区 366

13.4.2 访问设备的权限和设备保护 366

13.5 设备驱动程序和中断控制层 367

13.6 设备驱动程序的组织实例 368

13.6.1 设备驱动程序的工作原理 369

13.6.2 逻辑I/O与设备驱动程序接口 370

13.6.3 系统调用与驱动程序接口 373

13.7 设备驱动程序模块 374

13.6.4 安装中断处理程序 374

13.7.2 可动态加载和卸载的设备驱动程序模块 375

13.7.1 静态链接的设备驱动程序模块 375

13.8 了解系统基本配置 376

13.7.3 用户空间的设备驱动程序 376

13.8.2 内核中驱动程序清单 377

13.8.1 I/O端口 377

13.9 设备驱动程序中使用的内核函数 378

13.8.3 内核的中断报告显示 378

13.9.2 分配和释放内存的函数 379

13.9.1 操作I/O端口的函数 379

13.9.4 同步和计时要使用的内核函数 380

13.9.3 访问设备卡上内存的函数 380

13.9.5 中断管理内核函数 381

13.10.1 设备驱动程序与内核 383

13.10 编制设备驱动程序的基本方法 383

13.9.6 注册和注销设备的内核函数 383

13.9.7 其他内核函数 383

13.10.3 驱动程序与引导 388

13.10.2 驱动程序与硬件 388

13.11.1 编程用到的硬件 389

13.11 内核级设备驱动程序编程实例 389

13.11.2 上半部与下半部各自的功能 390

13.11.3 内核驱动程序的上半部编程 391

13.11.4 内核驱动程序的下半部编程 395

13.11.5 模块的安装与卸载 398

13.11.6 访问设备驱动程序的用户程序 399

13.11.7 编译设备驱动程序 400

13.12 小结 401

13.11.8 使用内核设备驱动程序模块 401

13.13 练习题 402

13.14 参考文献 403

14.2 信号机制 406

14.1 进程间通信的设计目标 406

第四部分 IPC和网络编程接口 406

第14章 最早的IPC方法:信号与管道 406

14.2.2 信号的产生与处理 407

14.2.1 什么是信号 407

14.3 发送信号 409

14.3.1 信号操作用到的数据结构 410

14.3.2 数据结构sigset_t上的一组简单操作函数 411

14.3.3 传送信号 412

14.4 接收信号 414

14.4.2 忽略信号 415

14.4.1 分析do_signal()函数 415

14.4.4 捕获一个信号 416

14.4.3 执行一个默认操作 416

14.5 捕获一个信号的编程实例 418

14.4.7 被中断的系统调用获得重新执行 418

14.4.5 执行信号处理程序 418

14.4.6 终止信号处理程序 418

14.6 管道 420

14.6.2 do_pipe()——创建一个管道 421

14.6.1 structpipe_inode_info数据结构 421

14.6.3 读管道 422

14.6.4 写管道 423

14.7 无名管道的编程实例 424

14.6.5 撤销管道 424

14.8.2 打开FIFO 425

14.8.1 创建一个FTFO 425

14.8 有名管道FIFO 425

14.9 编写有名管道的实用程序 426

14.8.3 读写FlFO 426

14.10 小结 427

14.12 参考文献 428

14.11 练习题 428

15.1.2 控制IPC资源的系统调用 429

15.1.1 创建IPC资源的系统调用 429

第15章 SystemV进程间通信 429

15.1 与IPC相关的系统调用 429

15.2 IPC资源中的公共元素及属性 430

15.1.4 IPC系统调用在i386体系结构中的实现 430

15.1.3 操作IPC资源的系统调用 430

15.3.1 与信号量操作相关的数据结构 432

15.3 IPC信号量 432

15.3.2 sys_semop()函数的功能 435

15.4 IPC信号量的编程示例 436

15.3.3 sys_semctl()函数的功能 436

15.6 IPC消息队列 438

15.5 信号量小结 438

15.6.1 与消息队列操作相关的数据结构 439

15.6.2 发送一个消息 440

15.6.3 接收消息和释放消息队列 441

15.7 IPC消息队列的编程示例 442

15.9.1 IPC共享内存的数据结构 443

15.9 共享内存 443

15.8 消息队列小结 443

15.9.2 连接IPC共享内存 445

15.9.4 剥离和释放IPC共享内存段 446

15.9.3 IPC共享内存请求调页的过程 446

15.10 IPC共享内存编程示例 447

15.12 练习题 451

15.11 小结 451

15.13 参考文献 452

16.1.1 OSI模型和网际协议族 453

16.1 Linux网络系统分层结构 453

第16章 Linux网络接口及内核实现 453

16.1.2 Linux网络协议族分层结构 454

16.2.1 传输控制协议——TCP 455

16.2 TCP和UDp 455

16.3.1 套接口地址结构 456

16.3 内核中与发送/接收相关的数据结构 456

16.2.2 用户数据报协议——UDP 456

16.3.2 数据包结构 457

16.3.3 建立网络连接的数据结构 461

16.3.4 协议操作函数使用的数据结构 464

16.4 网络连接的建立和关闭 465

16.4.1 网络连接的建立 466

16.4.2 关闭网络连接 470

16.5 发送数据 471

16.5.1 发送数据的系统调用接口 472

16.5.2 从INET协议层到IP层 473

16.5.3 IP层到硬件层的数据发送过程 474

16.5.4 硬件层的数据发送过程 475

16.6.1 接收数据的系统调用接口 476

16.6 接收数据 476

16.6.2 硬件层接收数据分析 477

16.6.3 从IP层接收数据 478

16.6.4 从INET层接收数据 479

16.7 小结 480

16.9 参考文献 481

16.8 练习题 481

17.1.1 socket()函数 482

17.1 套接口函数 482

第17章 TCP套接口编程的基本方法 482

17.1.2 其他套接口函数 483

17.2.1 建立TCF连接的过程 485

17.2 TCP连接的建立和终止过程 485

17.2.2 终止TCP连接的过程 486

17.3.2 TCP客户程序的实现 487

17.3.1 TCP客户程序设计方法 487

17.3 编制TCP客户程序 487

17.4.2 一个简单TCF服务器的实现 489

17.4.1 一个简单TCP服务器的编程方法 489

17.4 编制TCP服务器程序 489

17.4.3 TCP并发服务器的实现 491

17.7 参考文献 493

17.6 练习题 493

17.5 小结 493

18.1 UDP程序使用的套接口函数 494

第18章 UDP套接口编程的基本方法 494

18.2 发送UDP数据报的编程实例 495

18.3 接收UDP数据报的编程实例 496

18.5 练习题 498

18.4 小结 498

18.6 参考文献 499

附录 Linux源代码目录结构与内容 500