Linux内核完全注释
内核版本0.11(0.95)
赵 炯 著
www.oldlinux.org
gohigh@sh163.net
Linux 内核 0.11 完全注释
A Heavily Commented Linux Kernel Source Code
Linux Version 0.11
修正版 1.2.2
(Revision 1.2.2)
赵炯
Zhao Jiong
gohigh@sh163.net
www.plinux.org
www.oldlinux.org
2003-11-26
内容简介
本书对 Linux 早期操作系统内核(v0.11)全部代码文件进行了详细全面的注释和说明,旨在使读者能够在尽量短的时间
内对 Linux 的工作机理获得全面而深刻的理解,为进一步学习和研究 Linux 系统打下坚实的基础。虽然所选择的版本较低,
但该内核已能够正常编译运行,其中已经包括了 LINUX 工作原理的精髓,通过阅读其源代码能快速地完全理解内核的运作
机制。书中首先以 Linux 源代码版本的变迁历史为主线,详细介绍了 Linux 系统的发展历史,着重说明了各个内核版本之间
的重要区别和改进方面,给出了选择 0.11(0.95)版作为研究的对象的原因。另外介绍了内核源代码的组织结构及相互关系,
同时还说明了编译和运行该版本内核的方法。然后本书依据内核源代码的组织结构对所有内核程序和文件进行了注释和详细
说明。每章的安排基本上分为具体研究对象的概述、每个文件的功能介绍、代码内注释、代码中难点及相关资料介绍、与当
前版本的主要区别等部分。最后一章内容总结性地介绍了继续研究 Linux 系统的方法和着手点。
版权说明
作者保留本电子书籍的修改和正式出版的所有权利.读者可以自由传播本书全部和部分章节的内容,但需要注明出处.由
于目前本书尚为草稿阶段,因此存在许多错误和不足之处,希望读者能踊跃给予批评指正或建议.可以通过电子邮件给我发信
息:gohigh@sh163.net, 或直接来信至:上海同济大学 机械电子工程研究所(上海四平路 1239 号,邮编:200092).
© 2002,2003 by Zhao Jiong
© 2002,2003 赵炯 版权所有.
“RTFSC – Read The F**king Source Code ☺!”
–Linus Benedict Torvalds
目录
目录
序言................................................................................ 1
本书的主要目标 ........................................................ 1
现有书籍不足之处 .................................................... 1
阅读早期内核其它的好处? .................................... 2
阅读完整源代码的重要性和必要性 ........................ 2
如何选择要阅读的内核代码版本 ............................ 2
阅读本书需具备的基础知识 .................................... 3
使用早期版本是否过时? ........................................ 3
EXT2 文件系统与 MINIX 文件系统? ...................... 4
第 1 章 概述 .................................................................. 5
1.1 LINUX 的诞生和发展 ........................................... 5
1.2 内容综述 ............................................................. 9
1.3 本章小结 ........................................................... 12
第 2 章 LINUX 内核体系结构 .................................. 13
2.1 LINUX 内核模式 ................................................. 13
2.2 LINUX 内核系统体系结构 ................................. 14
2.3 LINUX 内核进程控制 ......................................... 15
2.4 LINUX 内核对内存的使用方法 ......................... 16
2.5 LINUX 内核源代码的目录结构 ......................... 18
2.6 内核系统与用户程序的关系............................ 23
2.7 LINUX 内核的编译实验环境 ............................. 23
2.8 LINUX/MAKEFILE 文件........................................ 25
2.9 本章小结 ........................................................... 33
第 3 章 引导启动程序(BOOT)............................. 35
3.1 概述 ................................................................... 35
3.2 总体功能 ........................................................... 35
3.3 BOOTSECT.S 程序 ................................................ 36
3.4 SETUP.S 程序 ....................................................... 43
3.5 HEAD.S 程序........................................................ 55
3.6 本章小结 ........................................................... 63
第 4 章 初始化程序(INIT)......................................... 65
4.1 概述 ................................................................... 65
4.2 MAIN.C 程序........................................................ 65
4.3 本章小结 ........................................................... 73
第 5 章 内核代码(KERNEL)..................................... 75
5.1 概述 ................................................................... 75
5.2 MAKEFILE 文件................................................... 78
5.3 ASM.S 程序.......................................................... 80
5.4 TRAPS.C 程序 ...................................................... 87
5.5 SYSTEM_CALL.S 程序.......................................... 94
5.6 MKTIME.C 程序 ................................................. 102
5.7 SCHED.C 程序.................................................... 104
5.8 SIGNAL.C 程序................................................... 116
5.9 EXIT.C 程序 ....................................................... 122
5.10 FORK.C 程序.................................................... 127
5.11 SYS.C 程序....................................................... 132
5.12 VSPRINTF.C 程序.............................................. 138
5.13 PRINTK.C 程序................................................. 146
5.14 PANIC.C 程序 ................................................... 147
5.15 本章小结........................................................ 148
第 6 章 块设备驱动程序(BLOCK DRIVER)......... 149
6.1 概述 ................................................................. 149
6.2 总体功能.......................................................... 149
6.3 MAKEFILE 文件................................................. 149
6.4 BLK.H 文件........................................................ 151
6.5 HD.C 程序.......................................................... 154
6.6 LL_RW_BLK.C 程序 ........................................... 167
6.7 RAMDISK.C 程序................................................ 171
6.8 FLOPPY.C 程序................................................... 175
第 7 章 字符设备驱动程序(CHAR DRIVER) ....... 189
7.1 概述 ................................................................. 189
7.2 总体功能描述.................................................. 189
7.3 MAKEFILE 文件................................................. 192
7.4 KEYBOARD.S 程序 ............................................. 194
7.5 CONSOLE.C 程序................................................ 211
7.6 SERIAL.C 程序 ................................................... 234
7.7 RS_IO.S 程序 ..................................................... 237
7.8 TTY_IO.C 程序................................................... 240
7.9 TTY_IOCTL.C 程序............................................. 250
第 8 章 数学协处理器(MATH)................................ 257
8.1 概述 ................................................................. 257
8.2 MAKEFILE 文件................................................. 257
8.3 MATH-EMULATION.C 程序.................................. 258
第 9 章 文件系统(FS)............................................... 261
9.1 概述 ................................................................. 261
9.2 总体功能描述.................................................. 261
9.3 MAKEFILE 文件................................................. 267
9.4 BUFFER.C 程序 .................................................. 269
9.5 BITMAP.C 程序................................................... 283
9.6 INODE.C 程序 .................................................... 288
9.7 SUPER.C 程序 .................................................... 298
9.8 NAMEI.C 程序.................................................... 306
9.9 FILE_TABLE.C 程序............................................ 328
9.10 BLOCK_DEV.C 程序.......................................... 328
- I -
目录
9.11 FILE_DEV.C 程序.............................................. 331
9.12 PIPE.C 程序...................................................... 333
9.13 CHAR_DEV.C 程序 ........................................... 337
9.14 READ_WRITE.C 程序........................................ 340
9.15 TRUNCATE.C 程序............................................ 343
9.16 OPEN.C 程序.................................................... 346
9.17 EXEC.C 程序.................................................... 352
9.18 STAT.C 程序 ..................................................... 366
9.19 FCNTL.C 程序 .................................................. 367
9.20 IOCTL.C 程序................................................... 369
第 10 章 内存管理(MM).......................................... 371
10.1 概述 ............................................................... 371
10.2 总体功能描述 ............................................... 371
10.3 MAKEFILE 文件............................................... 375
10.4 MEMORY.C 程序............................................... 377
10.5 PAGE.S 程序..................................................... 390
第 11 章 包含文件(INCLUDE) ............................... 393
11.1 概述 ............................................................... 393
11.2 INCLUDE/目录下的文件 ................................. 393
11.3 A.OUT.H 文件................................................... 393
11.4 CONST.H 文件 .................................................. 402
11.5 CTYPE.H 文件 .................................................. 402
11.6 ERRNO.H 文件 ................................................. 403
11.7 FCNTL.H 文件 .................................................. 405
11.8 SIGNAL.H 文件................................................. 407
11.9 STDARG.H 文件................................................ 409
11.10 STDDEF.H 文件 .............................................. 410
11.11 STRING.H 文件 ............................................... 410
11.12 TERMIOS.H 文件 ............................................ 420
11.13 TIME.H 文件................................................... 426
11.14 UNISTD.H 文件............................................... 428
11.15 UTIME.H 文件 ................................................ 433
11.16 INCLUDE/ASM/目录下的文件 ....................... 435
11.17 IO.H 文件....................................................... 435
11.18 MEMORY.H 文件............................................. 436
11.19 SEGMENT.H 文件 ........................................... 436
11.20 SYSTEM.H 文件.............................................. 439
11.21 INCLUDE/LINUX/目录下的文件 .................... 442
11.22 CONFIG.H 文件............................................... 442
11.23 FDREG.H 头文件 ............................................ 444
11.24 FS.H 文件....................................................... 447
11.25 HDREG.H 文件................................................ 452
11.26 HEAD.H 文件.................................................. 454
11.27 KERNEL.H 文件.............................................. 455
11.28 MM.H 文件..................................................... 456
11.29 SCHED.H 文件................................................ 456
11.30 SYS.H 文件..................................................... 464
11.31 TTY.H 文件..................................................... 466
11.32 INCLUDE/SYS/目录中的文件......................... 469
11.33 STAT.H 文件 ................................................... 469
11.34 TIMES.H 文件................................................. 470
11.35 TYPES.H 文件................................................. 471
11.36 UTSNAME.H 文件 ........................................... 472
11.37 WAIT.H 文件................................................... 472
第 12 章 库文件(LIB)............................................... 475
12.1 概述 ............................................................... 475
12.2 MAKEFILE 文件............................................... 475
12.3 _EXIT.C 程序 ................................................... 477
12.4 CLOSE.C 程序 .................................................. 478
12.5 CTYPE.C 程序 .................................................. 478
12.6 DUP.C 程序 ...................................................... 479
12.7 ERRNO.C 程序.................................................. 480
12.8 EXECVE.C 程序................................................ 480
12.9 MALLOC.C 程序............................................... 481
12.10 OPEN.C 程序 .................................................. 489
12.11 SETSID.C 程序................................................ 490
12.12 STRING.C 程序 ............................................... 491
12.13 WAIT.C 程序................................................... 491
12.14 WRITE.C 程序 ................................................ 492
第 13 章 建造工具(TOOLS) .................................... 493
13.1 概述 ............................................................... 493
13.2 BUILD.C 程序................................................... 493
参考文献 .................................................................... 501
附录 ............................................................................ 502
附录 1 内核主要常数............................................ 502
附录 2 内核数据结构............................................ 505
附录 3 80X86 保护运行模式 ................................. 512
索引 ............................................................................ 520
- II -
序言
序言
本书是一本有关 Linux 操作系统内核基本工作原理的入门读物。
本书的主要目标
本书的主要目标是使用尽量少的篇幅或在有限的篇幅内,对完整的 Linux 内核源代码进行解剖,以期
对操作系统的基本功能和实际实现方式获得全方位的理解。做到对 linux 内核有一个完整而深刻的理解,
对 linux 操作系统的基本工作原理真正理解和入门。
本书读者群的定位是一些知晓 Linux 系统的一般使用方法或具有一定的编程基础,但比较缺乏阅读目
前最新内核源代码的基础知识,又急切希望能够进一步理解 UNIX 类操作系统内核工作原理和实际代码实
现的爱好者。这部分读者的水平应该界于初级与中级水平之间。目前,这部分读者人数在 Linux 爱好者中
所占的比例是很高的,而面向这部分读者以比较易懂和有效的手段讲解内核的书籍资料不多。
现有书籍不足之处
目前已有的描述 Linux 内核的书籍,均尽量选用最新 Linux 内核版本(例如 Redhat 7.0 使用的 2.2.16
稳定版等)进行描述,但由于目前 Linux 内核整个源代码的大小已经非常得大(例如 2.2.20 版具有 268 万
行代码!),因此这些书籍仅能对 Linux 内核源代码进行选择性地或原理性地说明,许多系统实现细节被忽
略。因此并不能给予读者对实际 Linux 内核有清晰而完整的理解。
陆丽娜等同志翻译的 Scott Maxwell 著的一书《Linux 内核源代码分析》基本上是面对 Linux 中级水平
的读者,需要较为全面的基础知识才能完全理解。而且可能是由于篇幅所限,该书并没有对所有 Linux 内
核代码进行注释,略去了很多内核实现细节,例如其中内核中使用的各个头文件(*.h)、生成内核代码映象
文件的工具程序、各个 make 文件的作用和实现等均没有涉及。因此对于处于初中级水平之间的读者来说
阅读该书有些困难。
去年初浙江大学出版的《Linux 内核源代码情景分析》一书,也基本有这些不足之处。甚至对于一些
具有较高 Linux 系统应用水平的计算机本科高年级学生,由于该书篇幅问题以及仅仅选择性地讲解内核源
代码,也不能真正吃透内核的实际实现方式,因而往往刚开始阅读就放弃了。这在本人教学的学生中基本
都会出现这个问题。该书刚面市时,本人曾极力劝说学生购之阅读,并在二个月后调查阅读学习情况,基
本都存在看不下去或不能理解等问题,大多数人都放弃了。
John Lions 著的《莱昂氏 UNIX 源代码分析》一书虽然是一本学习 UNIX 类操作系统内核源代码很好
的书籍,但是由于其采用的是 UNIX V6 版,其中系统调用等部分代码是用早已过时的 PDP-11 系列机的汇
编语言编制的,因此在阅读与硬件部分相关的源代码时就会遇到较大的困难。
A.S.Tanenbaum 的书《操作系统:设计与实现》是一本有关操作系统内核实现很好的入门书籍,但该
书所叙述的 minix 系统是一种基于消息传递的内核实现机制,与 Linux 内核的实现有所区别。因此在学习
该书之后,并不能很顺利地即刻着手进一步学习较新的 Linux 内核源代码实现。
在使用这些书籍进行学习时会有一种“盲人摸象”的感觉,不能真正理解 Linux 内核系统具体实现的
整体概念,尤其是对那些 Linux 系统初学者或刚学会如何使用 Linux 系统的人在使用那些书学习内核原理
时,内核的整体运作结构并不能清晰地在脑海中形成。这在本人多年的 Linux 内核学习过程中也深有体会,
也是写作本书的动机之一。
为了填补这个空缺,本书的主要目标是使用尽量少的篇幅或在有限的篇幅内,对完整的 Linux 内核源
代码进行全面解剖,以期对操作系统的基本功能和实际实现方式获得全方位的理解。做到对 linux 内核有
一个完整而深刻的理解,对 linux 操作系统的基本工作原理真正理解和入门。
- 1 -
阅读早期内核其它的好处?
序言
目前,已经出现不少基于 Linux 早期内核而开发的专门用于嵌入式系统的内核版本,如 DJJ 的 x86 操
作系统、Uclinux 等(在 www.linux.org 上有专门目录),世界上也有许多人认识到通过早期 Linux 内核源代
码学习的好处,目前国内也已经有人正在组织人力注释出版类似本文的书籍。因此,通过阅读 Linux 早期
内核版本的源代码,的确是学习 Linux 系统的一种行之有效的途径,并且对研究和应用 Linux 嵌入式系统
也有很大的帮助。
在对早期内核源代码的注释过程中,作者已经发现,早期内核源代码几乎就是目前所使用的较新内核
的一个精简版本。其中已经包括了目前新版本中几乎所有的基本功能原理的内容。正如《系统软件:系统
编程导论》一书的作者 Leland L. Bach 在介绍系统程序以及操作系统设计时,引入了一种极其简化的简单
指令计算机(SIC)系统来说明所有系统程序的设计和实现原理,从而既避免了实际计算机系统的复杂性,又
能透彻地说明问题。这里选择 Linux 的早期内核版本作为学习对象,其指导思想与 Leland 的一致。这对
Linux 内核学习的入门者来说,无非是一个最理想的选择之一。能够在尽可能短的时间内深入理解 Linux
内核的基本工作原理。
当然,使用早期内核作为学习的对象也有不足之处,所选用的 Linux 早期内核版本不包含对虚拟文件
系统 VFS 的支持、对网络系统的支持、仅支持 a.out 执行文件和对其它一些现有内核中复杂子系统的说明。
但由于本书是作为 Linux 内核工作机理实现的入门教材,因此这也正是选择早期内核版本的优点之一。通
过学习本书,可以为进一步学习这些高级内容打下扎实的基础。
阅读完整源代码的重要性和必要性
正如 Linux 系统的创始人在一篇新闻组投稿上所说的,要理解一个软件系统的真正运行机制,一定要
阅读其源代码(RTFSC – Read The Fucking Source Code)。系统本身是一个完整的整体,具有很多看似不重
要的细节存在,但是若忽略这些细节,就会对整个系统的理解带来困难,并且不能真正了解一个实际系统
的实现方法和手段。
虽然通过阅读一些操作系统原理经典书籍(例如 M.J.Bach 的《UNIX 操作系统设计》)能够对 UNIX
类操作系统的工作原理有一些理论上的指导作用,但实际上对操作系统的真正组成和内部关系实现的理解
仍不是很清晰。正如 AST 所说的,“许多操作系统教材都是重理论而轻实践”,“多数书籍和课程为调度算
法耗费大量的时间和篇幅而完全忽略 I/O,其实,前者通常不足一页代码,而后者往往要占到整个系统三
分之一的代码总量。”内核中大量的重要细节均未提到。因此并不能让读者理解一个真正的操作系统实现
的奥妙所在。只有在详细阅读过完整的内核源代码之后,才会对系统有一种豁然开朗的感觉,对整个系统
的运作过程有深刻的理解。以后再选择最新的或较新内核源代码进行学习时,也不会碰到大问题,基本上
都能顺利地理解新代码的内容。
如何选择要阅读的内核代码版本
那么,如何选择既能达到上述要求,又不被太多的内容而搞乱头脑,选择一个适合的 Linux 内核
版本进行学习,提高学习的效率呢?作者通过对大量内核版本进行比较和选择后,最终选择了与目前 Linux
内核基本功能较为相近,又非常短小的 0.11 版内核作为入门学习的最佳版本。下图是对一些主要 Linux 内
核版本行数的统计。
- 2 -