Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

为什么写这本书

一本「都会一点」的困境

Linux 的学习材料从来不缺。缺的是把它们接起来的那根线。

命令行教程教你 ls、grep、sed;Shell 教程教你写脚本;系统编程手册从 open() 讲到 epoll();CSAPP 从二进制讲到链接和虚拟内存;内核书讲 task_struct、struct page 和 CFS;网络书讲 sk_buff 怎么从网卡走到 socket;运维书讲 systemd、LVM 和日志。每一本都很好,但它们各自站在自己的楼层,没有人告诉你楼梯在哪。

于是最常见的状态是:命令会用,但不知道 fork() 之后内核做了什么;能写多线程程序,但说不清 pthread_mutex_lock() 最终落到 futex 的哪条路径;能背 TCP 三次握手,但 listen() 的 backlog 满了以后内核到底丢不丢包;能看 top,但 %si 高的时候不知道该查软中断、NAPI 还是某个驱动的 ring。面试时能说出名词,排障时拿不出证据。

这本书要解决的正是这个断层。

一条主线:请求走过的路

全书用一条主线组织:一个用户请求,从键盘/网卡进入,经过 Shell、libc、系统调用、内核子系统、驱动,到达硬件;再把结果原路带回。

键盘/网卡 → 中断 → 内核入口 → 子系统(VFS/网络/调度/内存)
          → 驱动 → 硬件 → 返回用户态 → libc → 应用

这条线上每个停靠点,都对应母本里的一章:

停靠点你看到的现象背后的机制母本
$ ls目录列表Shell 展开、fork+exec、getdents64鸟哥 / Shotts / Kerrisk
open() 返回 3文件被打开路径解析、dentry/inode 缓存、fd 表Kerrisk / CSAPP / 奔跑吧
write() 很快返回数据「写完了」page cache、回写、fsync 的语义Kerrisk / OSTEP
malloc() 不总是进内核指针可用brk/mmap、slab、缺页CSAPP / 奔跑吧
accept() 返回新连接服务端收到请求三次握手、accept 队列、epoll网络 / 谢希仁
epoll_wait() 唤醒事件就绪等待队列、回调、就绪链表Kerrisk / 网络
top 里 %si 高CPU 在软中断NAPI、NET_RX_SOFTIRQ、ksoftirqd网络 / 奔跑吧

这张表是全书的目录,也是复习时的索引:忘了一个现象,先回到它所在的停靠点。

三条写作纪律

1. 先路径,后名词

每一个机制都从「谁调用谁、数据在哪、状态怎么变」讲起,再给结构体与源码。名词是路径的标签,不是起点。因此本书大量使用调用链、状态机、地址布局、时序图,而不是先摆一张 struct 定义。

2. 每个结论都要有证据

「write() 返回不代表落盘」不是一句口号,而是可以用 strace、/proc/meminfo、fio、bpftrace 验证的事实。本书的每个重要结论都尽量给出可复现的观测命令与预期输出。读完后你应该能自己设计实验,而不是记住结论。

3. 过时的内容不占主线

SysV init、ifconfig/route、iptables 旧语法、ext2 细节、32 位 x86 汇编、Linux 2.6 的 O(1) 调度器,这些内容仍然出现在很多教材里,但今天的主线是 systemd、iproute2、nftables、ext4/XFS/Btrfs、x86-64/ARM64、CFS/EEVDF。本书主线只讲现代做法,旧内容压缩进附录 A.1,只保留「为什么会变成今天这样」和「遇到旧系统怎么迁移」。

这本书不是什么

  • 不是十本书的读书笔记。它按知识依赖重新组织,母本只提供事实与边界;覆盖矩阵见附录 A.4。
  • 不是内核源码逐行注释。源码是证据,不是正文;正文讲路径与设计,源码片段只保留能说明问题的最小集。
  • 不是速成手册。它假设你愿意动手:每个项目都有可运行的代码、测试与压测,跳过项目只读正文,收获会少一半。
  • 不承诺「一遍就会」。系统知识需要反复在「现象—机制—证据」之间往返;本书用速查、回忆卡、自测卷和项目验收把这个往返固定下来。

怎么读

三条路线见学习路线:

  • 应用与运维:第 0 篇 → 第 4 篇前半 → 第 5 篇 → 项目 D;
  • 系统编程:第 0 篇精简 → 第 1 篇 → 第 2 篇 → 项目 A2/B/C;
  • 内核与性能:第 1 篇核心 → 第 2 篇 → 第 3 篇 → 第 4 篇后半 → 项目 A1/A3。

每条路线都给出「最小必读集」和「可以后补」的标记。第一遍不要追求全读;先把一条路线走通,再横向扩展。

关于版本

本书以 Ubuntu 24.04 LTS / Linux 6.8+ / glibc 2.39 / GCC 13 为基线,x86-64 为主、ARM64 对照。内核部分以 6.x 为主,涉及与 4.x/5.x 的差异时明确标注。命令示例默认在普通用户下运行,需要 root 的地方会写 sudo 或标 #。

致谢与版权

本书的结构来自十部经典教材的公开知识,正文、示例、图与项目均为重新撰写。引用原书观点时在页末注明「母本对应」,不摘录大段原文。若你是某本母本的作者或译者,认为某处归属标注不清,请通过仓库 issue 指出,我们会修正。

一句话:把「我知道这个名词」变成「我能沿着路径走一遍,并拿出证据」。