1.2 内容综述
本书主要对Linux的早期内核0.11版进行详细描述和注释。Linux-0.11版本是在1991年12月8日发布的。在发布时包括以下几个文件:
目前除了原来的rootimage.Z文件,其他四个文件均能找到。不过作者已经利用互联网上的资源为Linux 0.11重新制作了一个完全可以使用的rootimage-0.11根文件系统,并重新为其编译出能在0.11环境下使用的gcc 1.40编译器,配置出可用的实验开发环境。目前,这些文件均可以从oldlinux.org网站上下载。具体下载位置是:
http://oldlinux.org/Linux.old/images/该目录中含有已经制作好的内核映像文件boot-image和根文件系统映像文件rootimage。
http://oldlinux.org/Linux.old/kernel/该目录中含有内核源代码程序,包括本书所描述的Linux 0.11内核源代码程序。
http://oldlinux.org/Linux.old/bochs/该目录中含有已经设置好的运行在计算机仿真系统bochs下的Linux系统。
http://oldlinux.org/Linux.old/Linux-0.11/该目录中含有可以在Linux 0.11系统中使用的其他一些工具程序和说明文档。
本书分析了Linux 0.11内核中所有源代码程序,对每个源程序文件都进行了详细注释,包括对Makefile文件和.h头文件的注释。分析过程主要是按照计算机启动过程进行的。因此分析的连贯性到初始化结束内核开始调用shell程序为止。其余的各个程序均针对其自身进行分析,没有连贯性,因此可以根据自己的需要进行阅读。但在分析时还是提供了一些应用实例。
在分析过程中,如果第一次遇到较难理解的语句时,将给出相关知识的详细介绍。比如,在阅读代码第一次遇到C语言内嵌汇编代码时,将对GNU C语言的内嵌汇编语言进行较为详细的介绍;在遇到对中断控制器进行输入/输出操作时,将对Intel中断控制器(8259A)芯片给出详细的说明,并列出使用的命令和方法。这样做有助于加深对代码的理解,又能更好地了解所用硬件的使用方法,作者认为这种解读方法要比单独列出一章内容来总体介绍硬件或其他知识效率要高得多。
为了保持结构的完整性,对代码的说明是以内核中源代码的组成结构进行的,基本上是以每个源代码中的目录为一章内容进行介绍。整个Linux内核源代码的目录结构见表1-2。所有目录结构均以linux为当前目录。
表1-2 linux目录
本书内容可以分为三个部分。第1章至第4章是描述内核引导启动和32位运行方式的准备阶段,学习内核的初学者应该全部进行阅读。第二部分从第5章到第10章是内核代码的主要部分。其中第5章内容可以作为阅读本部分后续章节的索引。第11章到第13章是第三部分内容,可以作为阅读第二部分代码的参考。
第2章概要描述了Linux操作系统的体系结构,内核源代码文件放置的组织结构以及每个文件的大致功能。还介绍了Linux对物理内存的使用分配方式以及对虚拟线性地址的使用分配,以及如何在RedHat Linux 9操作系统上编译本书所讨论的Linux内核,对内核代码需要修改的地方。最后开始注释内核程序包中linux/目录下所看到的第一个文件,即内核代码的总体Makefile文件的内容。该文件是所有内核源程序的编译管理配置文件,供编译管理工具软件make使用。
第3章将详细注释boot/目录下的三个汇编程序,其中包括磁盘引导程序bootsect.s、获取BIOS中参数的setup.s汇编程序和32位运行启动代码程序head.s。这三个汇编程序完成了内核从块设备上引导加载到内存,对系统配置参数进行探测,完成了进入32位保护模式运行之前的所有工作,为内核系统进一步的初始化工作做好了准备。
第4章主要介绍init/目录中内核系统的初始化程序main.c。它是内核完成所有初始化工作并进入正常运行的关键。在完成了系统所有的初始化工作后,创建了用于shell的进程。在介绍该程序时将需要查看其所调用的其他程序,因此对后续章节的阅读可以按照这里调用的顺序进行。由于内存管理程序的函数在内核中被广泛使用,因此该章内容应该最先选读。当你能真正看懂直到main.c程序为止的所有程序时,就已经对Linux内核有了一定的了解,可以说有一半入门了,但还需要对文件系统、系统调用、各种驱动程序等进行更深一步的阅读。
第5章主要介绍kernel/目录中的所有程序。其中最重要的部分是进程调度函数schedule()、sleep_on()函数和有关系统调用的程序。此时你已经对其中的一些重要程序有所了解。
第6章对kernel/dev_blk/目录中的块设备程序进行了注释说明。该章主要含有硬盘、软盘等块设备的驱动程序,主要与文件系统和高速缓冲区打交道。因此,在阅读这章内容时需首先浏览一下文件系统的章节。
第7章对kernel/dev_chr/目录中的字符设备驱动程序进行注释说明。这一章中主要涉及串行线路驱动程序,键盘驱动程序和显示器驱动程序,因此含有较多与硬件有关的内容,在阅读时需要参考一下相关书籍。
第8章介绍kernel/math/目录中的数学协处理器的仿真程序。由于本书所注释的内核版本,还没有真正开始支持协处理器,因此本章的内容较少,也比较简单,只需有一般了解即可。
第9章介绍内核源代码fs/目录中的文件系统程序,在看这章内容时建议你能够暂停一下,先去阅读Andrew S. Tanenbaum的《操作系统:设计与实现》一书中有关MINIX文件系统的章节,因为最初的Linux系统只支持MINIX文件系统,Linux 0.11版也是如此。
第10章解说mm/目录中的内存管理程序。要透彻地理解这方面的内容,需要对Intel 80x86微处理器的保护模式运行方式有足够的理解,因此本章在适当的地方包含较为完整的有关80x86保护模式运行方式的说明,这些知识基本上都可以参考Intel 80386程序员编程手册(Intel 80386 Programmer′s Reference Manual)。但在此章中,以源代码中的运用实例为对象进行解说,可以更好地帮助读者理解它的工作原理。
现有的Linux内核分析书籍都缺乏对内核头文件的描述,因此对于一个初学者来讲,在阅读内核程序时会遇到许多障碍。本书的第11章对include/目录中的所有头文件进行了详细说明,基本上对每一个定义、每一个常量或数据结构都进行了详细注释。虽然该章内容主要是为阅读其他章节中的程序作参考使用的,但是若想彻底理解内核的运行机制,仍然需要了解这些头文件中的许多细节。
第12章介绍了Linux 0.11版内核源代码lib/目录中的所有文件。这些库函数文件主要向编译系统等系统程序提供接口函数,阅读这些文件对以后理解系统软件会有较大的帮助。由于这个版本较低,所以这方面的内容并不是很多,可以很快地看完。这也是我们选择0.11版的原因之一。
第13章介绍tools/目录下的build.c程序。这个程序并不包括在编译生成的内核映像(image)文件中,它仅用于将内核中的磁盘引导程序块与其他主要内核模块连接成一个完整的内核映像(kernel image)文件。