Linux内核完全注释pdf
内容简介夲书对早期Linuκ操作系统内核(v0.11)全部代码文件进行了详细全面的注释和说明,旨在让读者能够在尽量短的时间内对Iinuⅸ的工作机理获得全面而深刻的理解,为进一步学习和研究 Linux系统打下坚实的基础。虽然所选择的版木较低,但该內核已能够正常编译运行,并且其中包括了 LINUX工作原理的精髓。书中首先以 Linux源代码版本的变迁为主线,概要而有趣地介绍了 Linux系统的发長历史,同时着亘说明了各个内核版本之间的主要区别和改进方面,给岀了选择0.11(0.95)版内核源代码作为研究对象的原因。然后在正式开始描述内核源代码之前,概要介绍了运行 Linux系统的PC机的硬件组成结构、编制内核使用的汇编语言和¢浯言扩展邹分,并闬重点说明了80X86处理器仼保护模式下运行的编稈方法。接着我们详细介绍了Liux内核源代码目录树组织结构,并依据该组织结构对所有内核程序和文件进行了注释和详细说明有关代码注释的章节安排基本上都分为具体研宄对象的概述、每个文件的功能介绍、代码内注释、代码中难点及相关资料介绍等部分逐步展开。为了加深读者对内核工作原理的理解,书中最后一章给出了围绕 Linux0.11系统的多个试验。试验屮所使月的相关程序均可从本书配套网站(www.oldlinux.org)上下载木书适合作为高校计算机专业学生学习操作系统课程的辅助和实践教材,乜适合Linuⅹ爱好者作为学习內核工作原理的自学参考书籍,还可供一般技术人员作为开发嵌入式系统的参考书使用版权说明作者保留本电子书籍的修改和正式出版的所有权利读者可以自由传播本书全部和部分章节的内容,但需要注明出处由于目前木书仍然处于不断改进阶毁,囚此其中肯定还存在一些错误和不足之处。希望读者能踊跃绐予批评指正或良好建议。反馈信息可以通过电子邮件发给我: gohigh@sh163net或 gohigh@ gMail cur,也可直接来信至:上海同济大学电信工程学院计算机系(江建慧教授收),或杋械电∫工程研究所(赵炯收)(上海四丬路1239号,邮编:200092)o 2002-2007 by Zhao Jiong◎2002-2007赵炯版权所有RTFSC Read The Fxxking Source Code @!Linus benedict torvalds目录目录序言55LNUx的系统调用.16056系统时间和定时162本书的卞要日标57LNux进程控制现有书籍不足之处58 LINUX系统中堆栈的使用方法阅读早期内核的其他好处…59LNUX0.11采用的文件系统176阅读完整源代码的重要性和必要性510LNX内核源代码的目录结构177如何选择要阅读的内核代码版本….511内核系统与应用程序的关系…184阅读木书需具备的基础知识5.12 LINUX/MAKEFILE文件184使用早期版本是否过时?453本章小结189EXT2文件系统与ⅥNIX文件系统..4第6章引导启动程序(BOOT)…91第1章概述.6.1总体功能.1.1LNUX的诞生和发展56,2 BOOTSECTS程序1931.2内容综述1263 SETUP. S程序1.3木章小结1664HEAD.S程序221第2章微型计算机组成结构…1765本章小结23421微型计算机组成原理….17第7章初始化程序(INIT)23522IO端口寻址和访问控制方式…97.MAN.C程序…23523主存储器、BIOS和CMOS存储器….217.2环境初始化工作∴24724控制器和控制卡.73本章小结24925本章小结第8章内核代码( KERNEL)…251第3章内核编程语言和环境…3281总体功能3.1As86汇编器82 MAKEFILE文件2543,2 GNUAS汇编3883ASMS程序2563.3C语言程序4884 TRAPS.O程序.…26234C与汇编程序的相互调用.585 SYSTEM CALL.S程序26735 LINUX0.11目标文件格式86 MKTIME. C程序36MAKE程序和 MAKEFILE文件7287 SCHED C程序281第4章80X86保护模式及其编程……7588 SIGNAL.C程序89EXIC程序3114.|80X86系统寄存器和系统指令75810 FORK,, C程序42保护模式内存管理….8 I SYS.C程序32643分段机制8.12 VSPRINTF C程序33344分页机制813 PRINTK. C程序…3414.5保护998|4PANC.C程序3424.6中断和异常处理.…1108.5本章小结34347任务管理1204.8保护模式编程初始化.128第9章块设备驱动程序( BLOCK DRIVER…34549一个简单的多任务内核实例1319.总体功能346第5章 LINUX内核体系结构92 MAKEFILE文件34993BLKH文件3515.1LNUx内核模式14194IDC程序35552LNUx内核系统体系结杓…14295 LL RW BLK. C程序37853 LINUX内核对内存的管理和使用9.6 RAMDISK.C程序…38454中断机制15797LOYC程序.390目录第10章字符设备驱动程序( CHAR DRIVER)…41714.12TMEH文件12210.1总体功能14.13UNⅠSTD.文件724417102 MAKEFILE文件1414 UTIME.H文件72942710.3 KEYBOARD.S程序………14291415 INCLUDE/ASM/目求下的文件……73110.4 CONSOLE. C稈序14.16IoH文件73144810.5 SERIAL C程序…4l7 MEMORYH文件73247410.6RSlo.S程序4814.18 SEGMENT.H文件10.7 ITY OC程序14.19 SYSTEM.H文件3548710.8 TTY IOCTL.C程序l420 INCLUDE/ LINUX/目录下的文件7394991421 CONFIG.H文件∴739第11章数学协处理器(MATH)5071422 FDREGH头文件…741111 MAKEFILE文件……5071423FSH文件74412MATH- MULATION C程序5091424 HDREGH文件.7491425 HEAD. H文件752第12章文件系统(FS)……5111426 KERNEL,H文件175312.1总体功能5111427MMH文件.75412.,2 MAKEFILE文件5271428 SCHED.H文件123 BUFFER C程序5301429SYSH文件.76l124 BITMAP.C程序54714.30TTYH文件76312.5 TRUNCTE.C程序.…5531431 INCLUDE/sYs/目录中的文件12.6 INODE. C程序14.32STAT文件127 SUPER C程序.5671433 TIMES.H文件128 NAMELC程序…5771434 TYPES.H文件76812.9 FILE TABLE C程序60114.35 UTSNAME, H文件76912.10 BLOCK DEV.C程序1436wAIH文件77012.11 FILE DEV. C程序605第15章库文件(LIB)77312.12 PIPE, C程序60812.13 CHAR DEV.C程序612151 MAKEFILE文件……7412.14 READ WRITE C程序615152EXC程序.77612.150PNC程序62153 CLOSE.C程序…12.16EXEC.C程序627154 CTYPE. C程序77712.17 STATC程序…15.5DPC程序77812.|8 FCNTL. C程序156ERNO,C程序177912.19 IOCTL. C程序652157 EXECVE. C程序779158 MALLOC.O程序780第13章内存管理(MM)…655159 OPEN. C程序78913.1总体功能65515.10SESC程序.79013.2 MAKEFILE文件66115.1 L STRING C程序791133 MEMORY. C程序.66215.12WAIC程序791134 PAGES程序67915.13 WRITE C程序.…792第14章头文件( INCLUDE)n683第16章建造工具( TOOLS)…..…795141 INCLUDE/目录下的文件161 BUILD. O程序795142A.OUTI文件…684第17章实验环境设置与使用方法…802143 CONST.H文件695144 CTYPE.H文件17.1 BOCHS仿真系统80269514.5ERNO,H件…697172在 bochs中运行 LINUX0.11系统80614.6 FCNTL.H文件69917.3访问磁盘映像文件中的信息81314.7 SIGNAL.H文件…..1701174编译运行简单內核示例程序815148 STDARG.H文件.17.5利用 BOCHS调试内核817149 STDDEF H文件70417.6创建磁盘映像文件.14.10 STRINGH文件705177制作根文件系统827141 TERMIOS,H文件…715178在 LINUX0.11系统上编译0.1l内核…834179在 REDHAT9系统下编译 LINUX0.11内核.835目录17.10内核引导启动+根文件系统组成的集成盘838附录2ASCⅡ码表…17.11从硬盘启动:利用 SHOLLACE引导软件..843附录3常用C0、C1控制字符表17.12利用GDB和 BOCHS调试内核源代码…….846附录4常用转义序列和控制序列865参考文献853附录5第1套键盘扫描码集.868附录…s5索引869附录1内核数据结构.II序序言本是一本有关 Linux操作系统内核基本工作原理的入门读物。本书的主要目标本书的主要目标是使用尽量少的篇幅或在有限的篇幅内,对完整的 Linux内核源代码进行解剖,以期对操作系统的基本功能和实际实现方式获得全方位旳理解。做到对 linux内核有一个完整而深刻的理解,对linⅸx操作系统的基本工作原理真正理解和入门。本书读者群的定位是一些知晓 Linux系统的一般使用方法或具有一定的编程基础,但比较缺乏阅读目前最新内核源代码的基础知识,又急切希望能够迂一步理解UNⅨX类操作系统内核工作原理和实际代码实现的爱好者。这部分读者的水平应该界于初级与中级水平之间。目前,这部分读者人数在 Linux爱好者中所占的比例是很高的,而面向这部分读者以比较易懂和有效的手段讲解内核的书籍资料不多现有书籍不足之处目前已有的描述 Linux内核的书籍,均尽量选用最新 Linux内核版本(例如 Redhat7.0使用2.2.16、Fedora corc4使用2.6.11稳定版等)进行描述,但由于目前 Linux内核整个源代码的大小已经非常得大(例如2.220版就已具有268万行代码!),因比这些书籍仅能对Linx内核源代码进行选择性地或原理性地说明,许多系统实现细节被忽略。因此并不能给j读者对实际Liu内核有淸晰而完整的理解。Scott maxwell著的一书《 Linux内核源代码分析》(陆丽娜等译)基本上是面对 Linux中级水丬的读者,需要较为全面的基础知识才能完全理解。而且可能是由于篇幅所限,该书并没有对所有 Linux内核代码进行注释,略去了很多内核实现细节,例如其中内核中使用的各个头文件(*h)、生成内核代码映像文件的工具程序、各个make文件的作用和实现等均没有涉及。因此对于处于初中级水平之间的读者来说阅读该书有些困难浙江大学出版的《 Linux内核源代码情景分析》一书,也基本有这些不足之处。甚至对于一些具有较高 Linux系统应用水平的计算机本科高年级学生,由于该书篇幅问题以及仅仅选择性地讲解内核源代码,也不能真正吃透內核的实际实现方式,因而往往刚开始阅读就放弃了。该书刚面市时,本人曾板力劝说学生购之阅读,而在一个月后调査阅读学习情况时,基本都存仁看不下去或不能理解等问题,大多数人都放弃了。John lions著的《莱昂氐UNIX游代码分析》一书虽然是一本学习UNIX类操作系统内核源代码很好的书籍,但是由于其采用的是 UNIX V6版,其中系统调用等部分代码是用早已废弃的PDP-11系列机的汇编语言编制的,因此在阅读和理解与硬件部分相关的派代码时就会選到较大的闲难。A.S. Tanenbaum的书《操作系统:设计与实现》是一本有关操作系统内核实现很好的入门书籍,但该书所叙述的 MINIX系统是种基于消息传递的内核实现机制,与 Linux内核的实现有所区别。因此在学习该书之后,并不能很顺利地即刻着手进一步学习较新的 Linux内核溴代码实现在使用这些书籍进行学习时会有一种“盲人摸象”的感觉,不能真正理解 Linux内核系统具体实现的整体概念,尤其是对那些Linuκ系统初学者或刚学公如何使用 Linux系统的人在使用那些书学习内核原理时,内核的整体运作结构并不能凊晰地仨脑海中形成。这在本人多年的Iiuⅹ内核学习过程中也深序有体会。在1991年10月份, Linux的创始人 Linus torvald在开发出 Linux0.03版后写的一篇文章中也提到了同样的问题。在这篇题为“ LINUX- a free unix-386 kernel”的文章中,他说:“开发 Linux是为了那些操作系统爱好者和计算机科学系的学生使用、学习和娱乐”。“自由软件基金会的 GNU Hurd系统如果开发岀来就已经显得太庞大而不适合学习和理解。”而现今流行的 Linux系统要比当年GNU的Hurd系统更为庞大和复杂,因此同样也已经不适合作为操作系统初学者的入门学习起点。这也是作者基于Linux早期内核版本写作本书的动机之为了填补这个空缺,本书的主要目标是使用尽量少的篇幅或在有限的篇幅内,对完整的Liux内核源代码进行全面解剖,以期对操作系统的基本功能和实际实坝方式获得全方位的理解。做到对Liux内核有一个完整而深刻的理解,对Linuⅸx操作系统的基本工作原理真正理解和入门阅读早期内核的其他好处日前,已经出现不少基于 Linux早期内核而开发的专门用于嵌入式系统的内核版本,如DJJ的x86操作系统、Uclinux等(在www.linux.org上有专门目录),世界上也有许多人认识到通过早期Linux内核源代码学习的好处,目前国内也已经有人正在组织人力注释出版类似本文的书籍。因此,通过闶读 Linux早期内核版本的源代码,的确是学丬 Linux系统的种行之有效的途径,并且对研究和应用 Linux嵌入式系统也有很大的帮助在对早期内核源代码的注释过程中,作者发现,早期内核源代码几乎就是目前所使用的较新内核的个精简版本。其中已经包括了目前新版本中几乎所有的基本功能原理的内容。正如《系统软件:系统编程导论》一书的作者 Leland l.Beck在介绍系统程序以及操作系统设计时,引入了一和极其简化的简单指令计算机(SC)系统来说明所有系统程序的设计和实现原理,从而既避免了实际计算札系统的复杂性,乂能透彻地说明问题。这里选择 Linux的早期内核版本作为学习对象,其指导思想与 Leland的一致。这对 Linux内核学习的入门者来说,是最理想的选择之一。能够在尽可能短的时间内深入理解 Linux内核的基本工作原理对于那些已经比较熟悉内核工作原理的人,为了能让自己在实际工作中对系统的实际运转机制不产生一种空中楼阁的感觉,因此也有必要阅读内核源代码。当然,使用早期内核作为学习的对象也有不足之处。所选用的 Linux早期内核版本不包含对虚拟文件系统ⅤFS的支持、对网络系统的支持、仅支持a.out执行文件和对其他一些现有内核中复杂子系统的说明。但由于本书是作为Iinx内核工作机理实现的入门教材,因此这也正是选择早期内核版本的优点之一。通过学习本书,可以为进一步学习这些高级内容打下扎实的基础。阅读完整源代码的重要性和必要性正如Liux系统的创始人在篇新闻组投稿上所说的,要理解个软件系统的貞正运行机制,定要阅读其源代码( RTFSO- Read The Fucking Source Code)。系统木身是一个完整的整体,具有很多看似不重要的细节冇在,但是若忽略这些细节,就会对整个系统的理解带来困难,并且不能真正了解一个实际系统的实现方法和手段。虽然通过阅读一些操作系统原理经典书籍(例如 M.J. Bach的《UNX操作系统设计》能够对UNX类操作系统的工作原理有些理论上的指导作用,但实际上对操作系统的貞正组成和内部关系实现的理解仍不是很清晰。正如ΔST所说的,“许多操作系统教材都是重理论而轻实践”,“多数书籍和课程为调度算法耗费大量的时间和篇幅而完全忽畋IO,其实,前者通常不足一页代码,而后者往往要占到整个1原文可参见http://oldlinux.org/linus/序系统三分之一的代码总量。”内核中大量的重要细节均未提到。因此并不能让读者理解一个真正的操作系统实现的奥妙所在。只有在详细阅读过完整的内核源代码之后,才会对系统有一种豁然开朗的感觉,对整个系统的运作过程有深刻的理解。以后再选择最新的或较新内核源代码进行学习吋,也不会位到大问题,基本上都能顺利地理解新代码的内容。如何选择要阅读的内核代码版本那么,如何选择既能达到上述要求,又不被太多的内容而搞乱头脑,选择一个适合的 Linux内核版本进行学习,提髙学习的效率呢?作者通过对大量内核版本进行比较和选择后,最终选择了与目前 Linux内核基本功能较为相近,又非常短小的0.11版内核作为入门学习的最佳版本。下图是对一些主要 Linux内核版本行数的统计。Linux內核各版木源代码行数1000100105555555否日下下下后雨雨同内核版本号888目前的 Linux内核源代码量都在几百万行的数量上,2.60版内核代码行数约为592万行,极其庞大,对这些版本进行完全注释和说明几乎是不可能的。而0.11版内核不超过2万行代码量,因此完全可以在木书中鲜释和注释清楚。麻雀茧小,五脏俱全。为了对所研究的系统有感性的∫鲜,并能利用实验来加深对原理的理解,作者还专门重建了基于该内核的可运行的 Linux0.11系统。由于其中含有 GNU gcc编译环境,因此使用该系统也能做一些简单的开发工作。另外,使用该版本可以避免使用现有较新内核版本巾已经变得越米越复杂得各子系统部分的研宄(如虚拟文件系统ⅤFS、ex或ext3文件系统、网络子系统、新的复杂的内存管理机制等)。阅读本书需具备的基础知识在阅读本书时,读者必须具备一些基本的C语言知识和 Intel cPu汇编语言知识。有关C语言最佳的参考资料仍然是 Brain w. Kernighan和 Dennis m. Ritchie编写的《 The C Programming Language》一书而汇编语言的资料则可以参考任意一本讲解与 Intel cpu相关的汇编语言教材。另外还需要一些嵌入式汇编语言的资料。有关揿入式汇编的权威信息都包含在 gnU gcc编译器手册中。我们也可以从 Internet