引言

UNIX操作系统简单而一致,但只有天才(至少程序员)才能领会并欣赏其简单性。

——Dennis Ritchie

作者注:是的,我们疯了。预先警告:你们也会一样。

——Benny Goodheart 与James Cox

UNIX操作系统以简单、一致、优雅的设计著称,这种真正非凡的特性使得UNIX系统在超过1/4世纪的时间里影响了整个世界。而且,正是由于Linux的蓬勃发展,发源于UNIX的思想才依然活力依旧,并在可预见的未来其发展势头会一直持续下去。

UNIX和Linux操作系统带有某种强烈的吸引力,前述的两段引文很好地描述了这种吸引力的精神本质。UNIX操作系统诞生于贝尔实验室,Dennis Ritchie是其发明人之一。他在引文中提到,只有天才才能欣赏UNIX操作系统的简单性,这是否是完全正确的呢?显然不是,因为Ritchie在经过全面考虑后立即改口,称程序员也同样有资格欣赏UNIX操作系统。

UNIX和Linux操作系统的源代码复杂、文档少、对程序员的要求高,要想看懂这些代码并不是一件容易事。但只要一个人开始感受到内核源代码中所能获得的远见卓识,那就很难逃脱Linux的吸引力了。在此我给读者提出一个忠告:一旦开始潜心钻研操作系统内核,就很容易沉溺于此种乐趣之中。事实上,Benny Goodheart和James Cox在其书The Magic Garden Explained(该书解释了UNIX System V的内部实现机制)的序言中,早已对此做过说明(前文第二段引文)。当然,Linux肯定也能让读者发疯!

本书可用作指南和手册,引导读者阅读内核源代码,并使得读者能够更敏锐地体会到这些代码的美丽、优雅,以及相关概念在设计上的美学取向。当然,要理解内核,是有一些前提条件的。读者必须熟悉C语言。如果对您来说C只是一个字母,或者是一门外语,那可以休矣。操作系统绝非仅仅是一个“开始”按钮,熟悉少量相关的算法绝对是有益无害的。最后,如果读者对计算机体系结构有一定的了解,而不是仅仅知道如何造一个新奇的机箱,那就更有用了。从学术观点来看,上述要求比较接近于系统程序设计、算法和操作系统原理课程。本书的前一版本已经在几所大学用于向高年级本科生讲授Linux原理,我希望这一版也能用于同样的目的。

本书不可能对前述的所有主题都进行详细讲解,在读者思考拿在手里的这本大部头书的时候(当然也可能因为书太厚,没拿在手里),读者肯定会同意我的看法。如果某个主题与内核没有直接的关系,但对理解内核的运作机制是必需的,那么我会在书中相关之处简要介绍它。如果读者需要更透彻地理解相关知识,可以查阅我推荐的有关计算机原理方面的图书。市面上有大量的教科书可供选择,我觉得某些图书特别具有启发性,包括Brian W. Kernighan和Denis M. Ritchie的C Programming Language [KR88];Andrew S. Tanenbaum的Modern Operating Systems [Tan07](该书是关于一般操作系统的基础知识),Andrew S. Tanenbaum和Albert S. Woodhull的Operating Systems: Design and Implementation [TW06](该书是关于UNIX操作系统(Minix)的),W. Richard Stevens和Stephen A. Rago的《UNIX环境高级编程(第2版)》[SR05](该书是关于用户空间程序设计的),还有John L. Hennessy和David A. Patterson的两本书Computer ArchitectureComputer Organization and Design [HP06, PH07](这两本书是关于计算机体系结构基础的)。上述图书都是公认的经典。

此外,附录C包含了一些内核中用到的GNU C编译器扩展的相关信息,但这些扩展在一般的程序设计中并未广泛应用。

在撰写本书第一版时,内核的发布基本上不存在预定计划。正如我在附录F中讨论到的,这一点在内核2.6的开发期间发生了很大的变化,内核开发者在这方面做了很好的改进,开始以可预测的间隔周期性地发布新版本。我所讨论的内容集中于内核版本2.6.24,但也包含了一些对2.6.25和2.6.26版本的引用,这两个版本是在本书定稿后发布的,只不过发布时本书尚未出版。由于对整个内核的许多全面的修改已经合并到2.6.24版本,因此选择这个版本作为本书的目标还算是不错。虽然与本书中讨论的代码相比,在比较新版本的内核中,某些细节已经发生了变化,但大的方面会保持一段时间不会改变。

在讨论内核的各个组件和子系统时,我试图忽略不重要的细节,以避免使本书的篇幅过长。同样,我尽力保持本书的行文与内核源代码之间的联系。目前的情况还是比较幸运的,由于Linux的存在,使得我们能够查看一个真正的、可工作的、产品级操作系统的源代码,因此如果忽视了内核的这种本质性的方面,那将是可悲的。为保证书的篇幅不至于太长,我只能选择内核源代码中那些最关键的部分进行陈述。在理解Linux内核的结构和实现的过程中,阅读和使用实际的源代码是必不可少的一个步骤。附录F介绍了一些技巧,能够使得阅读和使用源代码容易一些。

关于Linux(和一般的UNIX操作系统)的一个特别有趣的事实是:它很能调动人的情绪。在因特网上有关操作系统的Flame wars(特指UseNet上的激烈争论)和热烈的技术辩论可能是一个例子,但有哪个UNIX以外的操作系统会专门有一本小册子(指The Unix-Haters Handbook[GWS94],由Simson Garfinkel等编辑)来论述憎恶这种系统到底有多好呢? 在为第一版写序言时,我提到,某个国际软件公司用难解的控告和争论来应对Linux,这对未来而言并不是坏信号。五年以后,形势已经改善,前述的厂商已经私下接受了下述的事实:Linux已经成为操作系统领域中一个重要的竞争者。在下一个五年,情况当然会变得更好。

毫不夸张,我承认自己肯定是被Linux迷住了(有时候,我可以肯定自己几乎因此而疯狂)。如果本书能够感染到你,那么我为写作此书付出的大量心血都是值得的!

改进建议和批评意见可以发送到wm@linux-kernel.net,或经由www.wrox.com反馈给我。当然,如果有人告诉我他很喜欢这本书,那我会非常高兴!

本书涵盖的内容

本书讨论了Linux内核的概念、结构和实现。各章分别介绍了下述主题。

  • 第1章概述Linux内核,讲述了内核的总体图景,后续章节则根据总体结构对内核进行更详细的研究。

  • 第2章讨论了多任务、调度和进程管理的基本知识,并分析了这些基本技术和概念抽象的实现方式。

  • 第3章讨论了如何管理物理内存。本章既讨论了内核与相关硬件的交互,也讨论了内核内部通过伙伴系统和slab分配器来分配内存的方式。

  • 第4章继续对内存进行讨论,讲解了用户空间的进程如何访问虚拟内存,以及在内核层面实现虚拟内存视图所需要的详细的数据结构和相关机制。

  • 第5章介绍了保证内核能够在多处理器系统上正确运作所需的机制。此外,本章还介绍了进程如何相互通信。

  • 第6章引导读者理解如何编写设备驱动程序,使内核支持新的硬件。

  • 第7章阐述了模块机制,该机制能够向内核动态添加新的功能。

  • 第8章讨论了虚拟文件系统,这是内核中一个一般的间接层,能够支持各种各样的不同文件系统,包括物理文件系统和虚拟文件系统。

  • 第9章讲解了Ext文件系统族,包括Ext2和Ext3文件系统,这是很多Linux系统安装的标准选项。

  • 第10章继续讨论文件系统,包括procfs和sysfs。这两个文件系统并非用来存储信息,而是向用户层提供关于内核的元信息。此外,本章阐述了一些减轻编写文件系统负担的方法。

  • 第11章给出了Ext文件系统属性和访问控制表的实现方式,这两者有助于提高系统的安全性。

  • 第12章讨论内核中网络的实现,内容集中于IPv4、TCP、UDP和netfilter。

  • 第13章介绍了系统调用的实现方式,系统调用是从用户层请求内核服务的标准机制。

  • 第14章对中断触发内核活动的方式进行了分析,并介绍了内核中将工作延迟至后续时间点执行的机制。

  • 第15章说明了内核对时间相关功能的处理,包括了高低两种分辨率的情形。

  • 第16章讨论了借助于页缓存和块缓存来加速内核操作。

  • 第17章讨论了如何对内存中缓存的数据与持久存储设备上的数据源进行同步。

  • 第18章介绍了页面回收和页交换的相关机制。

  • 第19章介绍了审计的实现,审计负责详细记录内核的活动。

  • 附录A讨论了内核所支持的各种计算机体系结构的特点。

  • 附录B简述了有效使用内核源代码的各种工具和方法。

  • 附录C提供了关于C语言的一些技术札记,并讨论了GNU C编译器的结构。

  • 附录D给出了内核的启动过程。

  • 附录E介绍了ELF二进制格式。

  • 附录F讨论了内核开发的许多社会性的方面,以及Linux内核社区。

目录

  • 版权声明
  • 致谢
  • 引言
  • 第1章 简介和概述
  • 第2章 进程管理和调度
  • 第3章 内存管理
  • 第4章 进程虚拟内存
  • 第5章 锁与进程间通信
  • 第6章 设备驱动程序
  • 第7章 模块
  • 第8章 虚拟文件系统
  • 第9章 Ext文件系统族
  • 第10章 无持久存储的文件系统
  • 第11章 扩展属性和访问控制表
  • 第12章 网络
  • 第13章 系统调用
  • 第14章 内核活动
  • 第15章 时间管理
  • 第16章 页缓存和块缓存
  • 第17章 数据同步
  • 第18章 页面回收和页交换
  • 第19章 审计
  • 附录A 体系结构相关知识
  • 附录B 使用源代码
  • 附录C 有关C语言的注记
  • 附录D 系统启动
  • 附录E ELF二进制格式
  • 附录F 内核开发过程
  • 参考文献