一本俯瞰Linux系统全局的书籍
2014-03-10
<<深度探索Linux操作系统>>是2013年才出版的新作.
该书刚出版不久我就入手了. 要说的话, 本人对技术书籍其实是蛮挑的, 一方面是因为我个人的书柜已经快放不下了, 另一方面作为一个在Linux系统环境下工作有了几年经验的 C 程序员, 懂得识别技术书籍的好坏. 所以我从来不肯往自己的书柜中添加哪怕一本我认为不够好的书籍.
其实我个人对于程序语言方面的涉猎还算广泛, 命令式的, 函数式的均略懂. 编译方面的书籍也翻过不少, 也尝试过自己写前端. 我称自己是一个 C 程序员的原因是我喜欢这门语言, 因为它强迫具有强烈好奇心的程序员去理解计算机系统和各种底层机制, 而这些东西在满足程序员的好奇心之后, 还会慢慢地令他着迷.
对于程序员来说, Linux 系统太容易让其沉迷其中了. 在古老的命令行终端下有各式各样的脚本解释器, 随手写几行就是一个可解释执行的程序. 而对 C 程序员来说, 和命令行操作方式浑然一体的编辑, 编译, 以及执行环境, 配合 shell 脚本和 Makefile, 一切是如此轻便灵动和随心所欲. 当了解并习惯了命令行上的各种操作之后, 有些时刻甚至会觉得各种笨重缓慢并向程序员隐瞒程序构建过程的IDE显得有些可笑.
从命令行和C语言开始, 程序员慢慢成长, 并开始越来越不满足. 看上去程序员所知道的越来越多, 知识亦日益丰富, 但是这些表面的知识越来越无法填满日益强烈的好奇心. 如果知识没有体系, 那么这些知识终究只是知识, 它们凌乱, 容易被忘却, 如同乡间田野中随处可见的小花朵. 而作为有智识的人类, 需要的是一整座种满各种品相花簇甚至奇珍异草的花园, 还要有一张花园的地图. 如此构建起来的体系, 方可称之为智慧.
然而构建体系却并非易事. 语言, 数据结构和算法, 编译原理, 计算机系统以及其下的硬件构架, 它们之间相互交叉渗入, 各种各样的机制甚至 trick 令人眼花缭乱. 若非深入花园数年, 又怎能辨得各色花香? 对程序员来说, 确是路漫漫其修远兮.
<<深度探索 Linux 操作系统>>一书的作者显然已经走过了足够漫长的道路. 当然, 其实我个人觉得本书的副标题更加切合其讲述的内容. 本书的优秀之处正是在于, 它以 Linux 系统为立足点, 讲述了一个完善的计算机系统体系. 更重要的是, 这种讲述不是大学那种照本宣科的讲述计算机系统的教材, 而是带有真正的实践意义的书籍.
本书首先从C语言的工具链开始, 讲述了一个 C 程序从源代码到最终可执行程序的构建过程. 首先分清楚工具链中各个工具的工作, 然后从汇编代码, 二进制文件格式以及链接器的工作入手, 确切地让 C 程序员清楚地掌握自己所写的程序的每一个字节. 作者的经验是如此老到, 刚好讲解了最需要被 C程序员所了解的内容 -- 但是, 以我工作了这些年的经验来看, 我发现并不是所有的 C程序员都了解作者所讲述的这些内容(对这些东西完全不了解的 C程序员, 我很难认同他们是合格的).
然后本书开始讲解内核的构建. 内核的映像如何组成, 内核的构建过程和配置. 该章讲述的脉络是如此的清晰可见, 确实印证了作者的话语, "实践检验真理". 接下来, 根文件系统, initramfs, 一步一步, 从内核开始, 一个可以实用的操作系统逐渐成型. 可能有的同学说, 这不跟 LFS(Linux From Scratch) 差不多的感觉么! 非也. LFS 确实也讲述系统构建, 然而在我看来, 二者虽形似, 而神远. 有没有听过"LFS 和 LFS 差距十万八千里"这句话? 对于一般的系统管理人员来说, 能够通过 LFS 构建一个可用系统已经相当不错了. 他们一般不会去深入到构建这些程序的细节, 以及内核的机理 -- 简单的说, 别想在 LFS 中看到代码啦. 但是本书则深入系统原理, 从内核本身的机制入手, 一些代码看似信手拈来, 实则若非深入实践, 绝无此等浑厚功力.
而从内核到用户空间, 则是程序员理解程序执行环境及其底层机理之精要! 众所周知, 进程乃为操作系统所须提供之首要抽象(另一个重要抽象是文件). 总体上来说, 我们可以将计算机系统抽象为一个三层构架: Application Layer, Kernel, Hardware, 即应用, 内核, 硬件. 所谓操作系统, 就是内核管理了所有硬件资源, 内核之上则运行着众多进程. Linux 内核以 task_struct 簿记一个进程的所有信息, 将其列入优先级队列, 调度辗转, 以呈纷繁精彩. 此中涉及之要, 又以内存管理为首. 内核为进程提供虚拟空间这一抽象, 使得进程以为自己处于一个有限而平坦的私有的存储器中, 并可使用系统所提供的一切资源. 然则, 程序如何加载以使其成为进程? 虚拟空间到物理存储的的映射若何? user space 到 kernel space 切换时需要保存哪些上下文信息... 均可在此书中找到答案. 而关于动态运行库之机理, 亦为理解程序执行环境之极重要一环. 本书也提供了关于此问题的深入解答.
本书后小半部分是关于构建一个实用的根文件系统, 以及, 建立图形环境. 有的同学觉得不应该讲这个 -- 而我的感觉正好相反. 要了解一个完整的系统是如何构建的, 图形环境是不可或缺的一部分. 即使是 Linus 本人看来, 在 Linux 之上构建图形环境也是一个好主意. 而且, 本书对图形环境的讲述正是从基础开始, 也是原理性的讲述. 这正好是我需要的. 本人 QT 和 GTK 都略懂, 能写点儿花里胡哨又没用的小程序. 可惜一直对 x11 不算清楚, 而本书的讲述解决了我不少疑问.
最后, 给本书做个总评.
其一. 本书的立足点是系统的构建和原理. 这意味着, 不能将本书当着是 Linux 内核源码解析一类来看. 某种程度上来说, 本书的立足点更高一些, 正如本文的标题所言, 是要宏观地俯瞰 Linux 系统的全局, 包括内核和应用层, 以及其相互交互的机制. 然而作者对 Linux 内核以及应用层机制的全面了解, 使得本书闪光点非常多, 信手拈来的代码和作者的深厚功底, 确实令人佩服.
其二. 本书的内容对读者亦有相当的要求. 要求读者对 Linux 系统, C语言, Shell, Makefile等等都有一定的熟识程度, 而且对 Linux 内核和计算机系统理论要有一些基本认识, 否则本书就是明珠暗投了.
鉴于本书对于初级程序员(而且本书主要针对 Linux 系统环境下的 C程序员)来说确实有一定难度, 这注定了本书的受众不会太广泛. 而本书对于 Linux 系统构建和原理方面的讲述确实非常出众, 是不可多得的优秀书籍. 对于 Linux 环境下喜欢 Linux 内核或者正在学习内核的同学或者Linux 内核驱动工程师等, 本书值得5星力荐!