深入 Linux 内核架构 PDF 文档
本书讨论了 Linux 内核的概念、结构和实现。主要内容包括多任务、调度和进程管理,物理内存的管理以及内核与相关硬件的交互,用户空间的进程如何访问虚拟内存,如何编写设备驱动程序,模块机制以及虚拟文件系统,Ext 文件系统属性和访问控制表的实现方式,内核中网络的实现,系统调用的实现方式,内核对时间相关功能的处理,页面回收和页交换的相关机制以及审计的实现等。此外,本书借助内核源代码中最关键的部分进行讲解,帮助读者掌握重要的知识点,从而在运用中充分展现 Linux 系统的魅力。
本书适合 Linux 内核爱好者阅读。
UNIX 操作系统以简单、一致、优雅的设计著称,这种真正非凡的特性使得 UNIX 系统在超过 1/4 世纪的时间里影响了整个世界。而且,正是由于 Linux 的蓬勃发展,发源于 UNIX 的思想才依然活力依旧,并在可预见的未来其发展势头会一直持续下去。
UNIX 和 Linux 操作系统带有某种强烈的吸引力,前述的两段引文很好地描述了这种吸引力的精神本质。UNIX 操作系统诞生于贝尔实验室,Dennis Ritchie 是其发明人之一。他在引文中提到,只有天才才能欣赏 UNIX 操作系统的简单性,这是否是完全正确的呢?显然不是,因为 Ritchie 在经过全面考虑后立即改口,称程序员也同样有资格欣赏 UNIX 操作系统。
目录
第 1 章 简介和概述
1.1 内核的任务
1.2 实现策略
1.3 内核的组成部分
1.3.1 进程、进程切换、调度
1.3.2 UNIX 进程
1.3.3 地址空间与特权级别
1.3.4 页表
1.3.5 物理内存的分配
1.3.6 计时
1.3.7 系统调用
1.3.8 设备驱动程序、块设备和字符设备
1.3.9 网络
1.3.10 文件系统
1.3.11 模块和热插拔
1.3.12 缓存
1.3.13 链表处理
1.3.14 对象管理和引用计数
1.3.15 数据类型
1.3.16 本书的局限性
1.4 为什么内核是特别的
1.5 行文注记
1.6 小结
第 2 章 进程管理和调度
2.1 进程优先级
2.2 进程生命周期
2.3 进程表示
2.3.1 进程类型
2.3.2 命名空间
2.3.3 进程 ID 号
2.3.4 进程关系
2.4 进程管理相关的系统调用
2.4.1 进程复制
2.4.2 内核线程
2.4.3 启动新程序
2.4.4 退出进程
2.5 调度器的实现
2.5.1 概观
2.5.2 数据结构
2.5.3 处理优先级
2.5.4 核心调度器
2.6 完全公平调度类
2.6.1 数据结构
2.6.2 CFS 操作
2.6.3 队列操作
2.6.4 选择下一个进程
2.6.5 处理周期性调度器
2.6.6 唤醒抢占
2.6.7 处理新进程
2.7 实时调度类
2.7.1 性质
2.7.2 数据结构
2.7.3 调度器操作
2.8 调度器增强
2.8.1 SMP 调度
2.8.2 调度域和控制组
2.8.3 内核抢占和低延迟相关工作
2.9 小结
第 3 章 内存管理
3.1 概述
3.2 (N)UMA 模型中的内存组织
3.2.1 概述
3.2.2 数据结构
3.3 页表
3.3.1 数据结构
3.3.2 页表项的创建和操作
3.4 初始化内存管理
3.4.1 建立数据结构
3.4.2 特定于体系结构的设置
3.4.3 启动过程期间的内存管理
3.5 物理内存的管理
3.5.1 伙伴系统的结构
3.5.2 避免碎片
3.5.3 初始化内存域和结点数据结构
3.5.4 分配器 API
3.5.5 分配页
3.5.6 释放页
3.5.7 内核中不连续页的分配
3.5.8 内核映射
3.6 slab 分配器
3.6.1 备选分配器
3.6.2 内核中的内存管理
3.6.3 slab 分配的原理
3.6.4 实现
3.6.5 通用缓存
3.7 处理器高速缓存和 TLB 控制
3.8 小结
第 4 章 进程虚拟内存
4.1 简介
4.2 进程虚拟地址空间
4.2.1 进程地址空间的布局
4.2.2 建立布局
4.3 内存映射的原理
4.4 数据结构
4.4.1 树和链表
4.4.2 虚拟内存区域的表示
4.4.3 优先查找树
4.5 对区域的操作
4.5.1 将虚拟地址关联到区域
4.5.2 区域合并
4.5.3 插入区域
4.5.4 创建区域
4.6 地址空间
4.7 内存映射
4.7.1 创建映射
4.7.2 删除映射
4.7.3 非线性映射
4.8 反向映射
4.8.1 数据结构
4.8.2 建立逆向映射
4.8.3 使用逆向映射
4.9 堆的管理
4.10 缺页异常的处理
4.11 用户空间缺页异常的校正
4.11.1 按需分配/调页
4.11.2 匿名页
4.11.3 写时复制
4.11.4 获取非线性映射
4.12 内核缺页异常
4.13 在内核和用户空间之间复制数据
4.14 小结
第 5 章 锁与进程间通信
5.1 控制机制
5.1.1 竞态条件
5.1.2 临界区
5.2 内核锁机制
5.2.1 对整数的原子操作
5.2.2 自旋锁
5.2.3 信号量
5.2.4 RCU 机制
5.2.5 内存和优化屏障
5.2.6 读者/写者锁
5.2.7 大内核锁
5.2.8 互斥量
5.2.9 近似的 per-CPU 计数器
5.2.10 锁竞争与细粒度锁
5.3 System V 进程间通信
5.3.1 System V 机制
5.3.2 信号量
5.3.3 消息队列
5.3.4 共享内存
5.4 其他 IPC 机制
5.4.1 信号
5.4.2 管道和套接字
5.5 小结
第 6 章 设备驱动程序
6.1 I/O 体系结构
6.2 访问设备
6.2.1 设备文件
6.2.2 字符设备、块设备和其他设备
6.2.3 使用 ioctl 进行设备寻址
6.2.4 主从设备号的表示
6.2.5 注册
6.3 与文件系统关联
6.3.1 inode 中的设备文件成员
6.3.2 标准文件操作
6.3.3 用于字符设备的标准操作
6.3.4 用于块设备的标准操作
6.4 字符设备操作
6.4.1 表示字符设备
6.4.2 打开设备文件
6.4.3 读写操作
6.5 块设备操作
6.5.1 块设备的表示
6.5.2 数据结构
6.5.3 向系统添加磁盘和分区
6.5.4 打开块设备文件
6.5.5 请求结构
6.5.6 BIO
6.5.7 提交请求
6.5.8 I/O 调度
6.5.9 ioctl 的实现
6.6 资源分配
6.6.1 资源管理
6.6.2 I/O 内存
6.6.3 I/O 端口
6.7 总线系统
6.7.1 通用驱动程序模型
6.7.2 PCI 总线
6.7.3 USB
6.8 小结
第 7 章 模块
7.1 概述
7.2 使用模块
7.2.1 添加和移除
7.2.2 依赖关系
7.2.3 查询模块信息
7.2.4 自动加载
7.3 插入和删除模块
7.3.1 模块的表示
7.3.2 依赖关系和引用
7.3.3 模块的二进制结构
7.3.4 插入模块
7.3.5 移除模块
7.4 自动化与热插拔
7.4.1 kmod 实现的自动加载
7.4.2 热插拔
7.5 版本控制
7.5.1 校验和方法
7.5.2 版本控制函数
7.6 小结
第 8 章 虚拟文件系统
8.1 文件系统类型
8.2 通用文件模型
8.2.1 inode
8.2.2 链接
8.2.3 编程接口
8.2.4 将文件作为通用接口
8.3 VFS 的结构
8.3.1 结构概观
8.3.2 inode
8.3.3 特定于进程的信息
8.3.4 文件操作
8.3.5 目录项缓存
8.4 处理 VFS 对象
8.4.1 文件系统操作
8.4.2 文件操作
8.5 标准函数
8.5.1 通用读取例程
8.5.2 失效机制
8.5.3 权限检查
8.6 小结
第 9 章 Ext 文件系统族
9.1 简介
9.2 Ext2 文件系统
9.2.1 物理结构
9.2.2 数据结构
9.2.3 创建文件系统
9.2.4 文件系统操作
9.3 Ext3 文件系统
9.3.1 概念
9.3.2 数据结构
9.4 小结
第 10 章 无持久存储的文件系统
10.1 proc 文件系统
10.1.1 /proc 的内容
10.1.2 数据结构
10.1.3 初始化
10.1.4 装载 proc 文件系统
10.1.5 管理/proc 数据项
10.1.6 读取和写入信息
10.1.7 进程相关的信息
10.1.8 系统控制机制
10.2 简单的文件系统
10.2.1 顺序文件
10.2.2 用 libfs 编写文件系统
10.2.3 调试文件系统
10.2.4 伪文件系统
10.3 sysfs
10.3.1 概述
10.3.2 数据结构
10.3.3 装载文件系统
10.3.4 文件和目录操作
10.3.5 向 sysfs 添加内容
10.4 小结
第 11 章 扩展属性和访问控制表
11.1 扩展属性
11.1.1 到虚拟文件系统的接口
11.1.2 Ext3 中的实现
11.1.3 Ext2 中的实现
11.2 访问控制表
11.2.1 通用实现
11.2.2 Ext3 中的实现
11.2.3 Ext2 中的实现
11.3 小结
第 12 章 网络
12.1 互联的计算机
12.2 ISO/OSI 和 TCP/IP 参考模型
12.3 通过套接字通信
12.3.1 创建套接字
12.3.2 使用套接字
12.3.3 数据报套接字
12.4 网络实现的分层模型
12.5 网络命名空间
12.6 套接字缓冲区
12.6.1 使用套接字缓冲区管理数据
12.6.2 管理套接字缓冲区数据
12.7 网络访问层
12.7.1 网络设备的表示
12.7.2 接收分组
12.7.3 发送分组
12.8 网络层
12.8.1 IPv4
12.8.2 接收分组
12.8.3 交付到本地传输层
12.8.4 分组转发
12.8.5 发送分组
12.8.6 netfilter
12.8.7 IPv6
12.9 传输层
12.9.1 UDP
12.9.2 TCP
12.10 应用层
12.10.1 socket 数据结构
12.10.2 套接字和文件
12.10.3 socketcall 系统调用
12.10.4 创建套接字
12.10.5 接收数据
12.10.6 发送数据
12.11 内核内部的网络通信
12.11.1 通信函数
12.11.2 netlink 机制
12.12 小结
第 13 章 系统调用
13.1 系统程序设计基础
13.1.1 追踪系统调用
13.1.2 支持的标准
13.1.3 重启系统调用
13.2 可用的系统调用
13.3 系统调用的实现
13.3.1 系统调用的结构
13.3.2 访问用户空间
13.3.3 追踪系统调用
13.4 小结
第 14 章 内核活动
14.1 中断
14.1.1 中断类型
14.1.2 硬件 IRQ
14.1.3 处理中断
14.1.4 数据结构
14.1.5 中断电流处理
14.1.6 初始化和分配 IRQ
14.1.7 处理 IRQ
14.2 软中断
14.2.1 开启软中断处理
14.2.2 软中断守护进程
14.3 tasklet
14.3.1 创建 tasklet
14.3.2 注册 tasklet
14.3.3 执行 tasklet
14.4 等待队列和完成量
14.4.1 等待队列
14.4.2 完成量
14.4.3 工作队列
14.5 小结
第 15 章 时间管理
15.1 概述
15.1.1 定时器的类型
15.1.2 配置选项
15.2 低分辨率定时器的实现
15.2.1 定时器激活与进程统计
15.2.2 处理 jiffies
15.2.3 数据结构
15.2.4 动态定时器
15.3 通用时间子系统
15.3.1 概述
15.3.2 配置选项
15.3.3 时间表示
15.3.4 用于时间管理的对象
15.4 高分辨率定时器
15.4.1 数据结构
15.4.2 设置定时器
15.4.3 实现
15.4.4 周期时钟仿真
15.4.5 切换到高分辨率定时器
15.5 动态时钟
15.5.1 数据结构
15.5.2 低分辨率系统下的动态时钟
15.5.3 高分辨率系统下的动态时钟
15.5.4 停止和启动周期时钟
15.6 广播模式
15.7 定时器相关系统调用的实现
15.7.1 时间基准
15.7.2 alarm 和 setitimer 系统调用
15.7.3 获取当前时间
15.8 管理进程时间
15.9 小结
第 16 章 页缓存和块缓存
16.1 页缓存的结构
16.1.1 管理和查找缓存的页
16.1.2 回写修改的数据
16.2 块缓存的结构
16.3 地址空间
16.3.1 数据结构
16.3.2 页树
16.3.3 地址空间操作
16.4 页缓存的实现
16.4.1 分配页
16.4.2 查找页
16.4.3 在页上等待
16.4.4 对整页的操作
16.4.5 页缓存预读
16.5 块缓存的实现
16.5.1 数据结构
16.5.2 操作
16.5.3 页缓存和块缓存的交互
16.5.4 独立的缓冲区
16.6 小结
第 17 章 数据同步
17.1 概述
17.2 pdflush 机制
17.3 启动新线程
17.4 线程初始化
17.5 执行实际工作
17.6 周期性刷出
17.7 相关的数据结构
17.7.1 页状态
17.7.2 回写控制
17.7.3 可调参数
17.8 中央控制
17.9 超级块同步
17.10 inode 同步
17.10.1 遍历超级块
17.10.2 考察超级块 inode
17.10.3 回写单个 inode
17.11 拥塞
17.11.1 数据结构
17.11.2 阈值
17.11.3 拥塞状态的设置和清除
17.11.4 在拥塞队列上等待
17.12 强制回写
17.13 膝上模式
17.14 用于同步控制的系统调用
17.15 完全同步
17.15.1 inode 的同步
17.15.2 单个文件的同步
17.15.3 内存映射的同步
17.16 小结
第 18 章 页面回收和页交换
18.1 概述
18.1.1 可换出页
18.1.2 页颠簸
18.1.3 页交换算法
18.2 Linux 内核中的页面回收和页交换
18.2.1 交换区的组织
18.2.2 检查内存使用情况
18.2.3 选择要换出的页
18.2.4 处理缺页异常
18.2.5 缩减内核缓存
18.3 管理交换区
18.3.1 数据结构
18.3.2 创建交换区
18.3.3 激活交换区
18.4 交换缓存
18.4.1 标识换出页
18.4.2 交换缓存的结构
18.4.3 添加新页
18.4.4 搜索一页
18.5 数据回写
18.6 页面回收
18.6.1 概述
18.6.2 数据结构
18.6.3 确定页的活动程度
18.6.4 收缩内存域
18.6.5 隔离 LRU 页和集中回收
18.6.6 收缩活动页链表
18.6.7 回收不活动页
18.7 交换令牌
18.8 处理交换缺页异常
18.8.1 换入页
18.8.2 读取数据
18.8.3 交换预读
18.9 发起内存回收
18.9.1 用 kswapd 进行周期性内存回收
18.9.2 在严重内存不足时换出页
18.10 收缩其他缓存
18.10.1 数据结构
18.10.2 注册和删除收缩器
18.10.3 收缩缓存
18.11 小结
第 19 章 审计
19.1 概述
19.2 审计规则
19.3 实现
19.3.1 数据结构
19.3.2 初始化
19.3.3 处理请求
19.3.4 记录事件
19.3.5 系统调用审计
19.4 小结
附录 A 体系结构相关知识
A.1 概述
A.2 数据类型
A.3 对齐
A.4 内存页面
A.5 系统调用
A.6 字符串处理
A.7 线程表示
A.8 位操作和字节序
A.9 页表
A.10 杂项
A.11 小结
附录 B 使用源代码
B.1 内核源代码的组织
B.2 用 Kconfig 进行配置
B.3 用 Kbuild 编译内核
B.4 有用的工具
B.5 调试和分析内核
B.6 用户模式 Linux
B.7 小结
附录 C 有关 C 语言的注记
C.1 GNU C 编译器如何工作
C.2 内核的标准数据结构和技术
C.3 小结
附录 D 系统启动
D.1 IA-32 系统上与体系结构相关的设置
D.2 高层初始化
D.3 小结
附录 E ELF 二进制格式
E.1 布局和结构
E.2 内核中的数据结构
E.3 小结
附录 F 内核开发过程
F.1 简介
F.2 内核代码树和开发的结构
F.3 补丁的结构
F.4 Linux 和学术界
F.5 小结
参考文献
下载地址:https://www.wenjiangs.com/wp-content/uploads/2024/04/UbUtBgLCToMcqq4g.zip
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论