《LINUX内核源代码情景分析》
毛德操、胡希明 著 上下册合订完整版,1575 页,基于 Linux 2.4 内核(i386 架构) 浙江大学出版社,2001 年
一、书籍定位与特色
这是一本国内 Linux 内核领域的里程碑式著作。与《深入理解Linux内核》(ULK)侧重概念讲解不同,本书采用**“情景分析”(Scenario Analysis)方法**:从一个具体的系统调用或操作场景出发,沿着代码执行路径深入,逐步展开内核各模块的运行机制。
核心特色:
- 源码驱动:每一章都以真实的 Linux 2.4 内核源码片段为骨架,逐行讲解
- 情景切入:从用户态的一个系统调用(如 fork、exec、open、socket)出发,跟踪到内核深处
- 数据结构先行:先讲清关键数据结构(task_struct、mm_struct、inode、buffer_head 等),再讲操作流程
- i386 架构为载体:所有机制都结合 x86 硬件特性(段页式管理、特权级、中断描述符表等)讲解
- 上下两册合订:上册覆盖存储管理、进程、文件系统;下册覆盖中断与系统调用、进程通信、设备驱动、文件系统(续)、系统结构、网络
二、全书知识架构
上册(存储 / 进程 / 文件系统)
第1章 预备知识
- Linux 内核的历史与发展(Unix → Minix → Linux → GNU 配套)
- Linux 的版权与 GPL 规则(Copyleft vs Copyright)
- i386 保护模式:段式内存管理(段描述符、GDT/LDT、段寄存器结构)
- 页式内存管理:页目录、页表、页式虚存实现、PSE(4MB 大页)
- 保护模式下的特权级与地址转换全流程
第2章 存储管理
- 地址映射与页目录:线性地址到物理地址的两级页表转换
- 物理页面管理:mem_map 数组、伙伴系统(Buddy System)、zone 管理
- 虚存管理:mm_struct、vm_area_struct、虚存区间的分配与回收
- 页面异常(Page Fault):缺页中断的处理流程、写时复制(COW)、按需调页
- 页换出机制:kswapd 内核线程、page_launder(脏页清洗)、活跃/非活跃链表
- 内核内存分配:kmalloc、vmalloc、slab 分配器
- 反向映射(reverse mapping)、页面回收策略
第3章 进程
- 进程描述符 task_struct:全结构剖析,状态、优先级、上下文、资源
- 进程调度:schedule() 函数、调度策略(SCHED_OTHER / SCHED_FIFO / SCHED_RR)、 goodness() 权重计算
- 定时器机制:timer_bh()、run_timer_list()、定时器队列、进程超时唤醒(schedule_timeout)
- 系统调用 fork / clone:写时复制、task_struct 复制、资源继承
- execve 系统调用:可执行文件加载、ELF 格式、进程地址空间重建
- exit 与 wait:进程退出、僵尸进程、资源回收
- 内核线程:内核线程的创建与用途(kswapd、kflushd 等)
第4章 文件系统(上册部分)
- VFS 抽象层:超级块、inode、dentry、file 四大对象
- Ext2 文件系统:磁盘布局、块组、inode 位图、块位图、目录项
- 文件的打开与读写:open() 系统调用路径、dentry 缓存、page cache
- 目录操作:路径名查找、符号链接、硬链接
- 访问权限:UNIX 权限模型、ACL 雏形
下册(中断 / IPC / 驱动 / 网络 / 系统结构)
第5章 中断、异常与系统调用
- 中断向量表 IDT:32 个异常 + 16 个 IRQ + 系统调用 + 自定义中断
- 中断处理流程:现场保存 → ISR 执行 → 中断下半部(bottom half / tasklet)
- 异常处理:Page Fault、General Protection、Syscall 等
- 系统调用机制:int 0x80、系统调用表、参数传递、返回值
- 时钟中断:全局时钟、进程时间片、定时器驱动
第6章 进程间通信
- 管道(Pipe):创建、读写、阻塞/非阻塞、与 dup2/exec 配合实现 shell 管道
- 命名管道(FIFO):与管道的区别、文件系统节点
- 信号(Signal):信号机制、信号处理函数、信号队列、实时信号
- System V IPC:消息队列、共享内存、信号量
- 套接字 IPC:Unix 域套接字(AF_UNIX)、流式/数据报套接字的连接与数据传输
第7章 设备驱动
- 字符设备驱动:主设备号/次设备号、file_operations 接口、ioctl
- 块设备驱动:block_device、buffer_head、请求队列(request queue)、电梯算法(Elevator)
- 块缓冲机制:buffer cache 与 page cache 的关系、getblk()、brelse()
- 块设备读写流程:ll_rw_block() → 提交请求 → 中断回调
- Ramdisk 驱动:内存模拟磁盘的实现
- IDE 硬盘驱动:ATA 协议、PIO 模式、中断驱动
第8章 文件系统(续)
- 文件系统的安装与拆卸:mount/umount 系统调用、vfsmount 结构
- Proc 文件系统:虚拟文件系统实现、/proc 下各文件的内核接口
- Minix / Devpts / Sysfs 等特殊文件系统
- 页回写机制:bdflush 内核线程、脏页刷新、kupdate
- 文件锁:劝告锁(advisory lock)、强制锁(mandatory lock)、flock / fcntl
第9章 系统结构
- SMP 多处理器:SMP 启动、CPU ID、per-CPU 数据、调度亲和性
- 中断控制器 APIC:本地 APIC、I/O APIC、中断路由
- 多处理器同步:自旋锁(spinlock)、读写锁、原子操作、内存屏障
- 系统引导与启动:BIOS → bootsect → setup → head.S → start_kernel 全流程
- 系统重启与关机:reboot 系统调用、三重故障重启、通过 BIOS 重启
- 模块机制:module_init/module_exit、insmod/rmmod、符号导出
第10章 网络
- 网络协议栈架构:BSD Socket 层 → INET 层 → 传输层 → 网络层 → 数据链路层
- 套接字创建与绑定:socket()、bind() 系统调用在内核中的路径
- TCP 连接建立:三次握手的内核实现、listen/accept/connect
- TCP 数据传输:send/recv、滑动窗口、拥塞控制(待确认深度)
- UDP 传输:无连接数据报的发送与接收
- IP 层:路由、分片与重组、IP 选项
- 网络设备驱动:net_device 结构、数据包接收 NAPI 雏形
三、核心方法:情景分析怎么读
本书的最大价值在于教会读者”怎么读内核源码”,而不仅是讲清内核做了什么。情景分析的方法论:
- 从一个具体场景切入:比如”当用户调用 fork() 时发生了什么”
- 沿调用链向下追踪:用户态 → 系统调用入口 → 内核函数 → 更底层函数
- 遇到数据结构就先搞懂:结构决定操作,操作反哺结构理解
- 关注特殊路径:错误处理、竞态条件、资源回收
- 结合硬件理解:x86 的 MMU、中断、特权级不是抽象概念,是内核运行的物理基础
四、重点章节与阅读路径
入门路径(前三章打底)
预备知识 → 存储管理 → 进程 → 文件系统基础
深入路径
中断与系统调用 → IPC → 设备驱动 → 系统结构
高阶路径
网络协议栈 → SMP → 模块机制
五、本书的历史地位与局限
历史地位
- 国内最早系统深入讲解 Linux 内核源码的中文著作之一
- 影响了一代 Linux 内核开发者,很多人的内核入门书
- 源码级深度,至今仍有参考价值(核心机制变化不大)
局限
- 内核版本老:基于 Linux 2.4,与现代 5.x/6.x 内核有显著差异
- 调度器:2.4 是 O(n) 调度器 → 后来演进为 O(1) → CFS
- 内存管理:2.4 的页回收、反向映射比较原始
- 无 Cgroup、namespace、eBPF 等现代特性
- 架构单一:只讲 i386,没有 ARM 等多架构视角
- 网络部分较浅:TCP/IP 栈的深度不及存储管理和进程部分
- 没有块设备 I/O 调度器的现代演进(CFQ、Deadline、Kyber 等均为后来加入)
六、与其他经典著作的关系
| 书籍 | 侧重点 | 与本书关系 |
|---|---|---|
| 《深入理解Linux内核》(ULK) | 概念与机制,源码为辅 | 互补,ULK 更系统、版本更新 |
| 《Linux内核设计与实现》(Robert Love) | 概览与原理,薄而精 | 入门更好,本书更深 |
| 《深入Linux内核架构》(PLKA) | 现代内核(2.6),更全面 | 本书的现代继任者 |
| 本书 | 源码逐行、情景追踪 | 代码细节最丰富,适合想”读源码”的读者 |
七、关联笔记
- 《Linux内核设计与实现》-第三版-Robert-Love — Robert Love 的经典入门,与本书互补
- 《结构化计算机组成》-Structured-Computer-Organization-第6版-Tanenbaum — 硬件基础,帮助理解 i386 保护模式部分
- 《程序员的自我修养》-链接、装载与库 — 程序装载与运行的用户态视角,与本书 exec/进程部分互补
注:本文件基于 Linux 2.4 内核版本的经典教材整理。现代 Linux 内核(5.x/6.x)在调度器、内存管理、cgroup、eBPF、IO_uring 等方面已有重大演进,阅读时需注意版本差异。