猜你喜欢
Linux 内核完全剖析 基于0.12内核 15周年版

Linux 内核完全剖析 基于0.12内核 15周年版

书籍作者:赵炯 ISBN:9787111744191
书籍语言:简体中文 连载状态:全集
电子书格式:pdf,txt,epub,mobi,azw3 下载次数:2646
创建日期:2024-06-25 发布日期:2024-06-25
运行环境:PC/Windows/Linux/Mac/IOS/iPhone/iPad/Kindle/Android/安卓/平板
内容简介
本书对 Linux 操作系统早期内核(V0.12)全部源代码文件进行了详
细、全面的注释和说明,旨在帮助读者用较短的时间对 Linux 的工作机理
获得全面而深刻的理解,为进一步学习和研究现代 Linux 系统打下坚实的
基础。虽然分析的版本较低,但该内核已能够正常编译运行,并且其中已
包括了 Linux 工作原理的精髓。书中首先概要地介绍了 Linux 内核发展历
史,说明了各内核版本之间的主要区别和改进,给出了选择 0.12 版内核源
代码作为研究对象的原因。然后给出了阅读内核源代码所需的相关基础知
识,概要介绍了运行 Linux 系统的 PC 硬件组成结构、编写内核使用的汇编
语言和 C 语言扩展部分,并且重点说明了 80x86 处理器在保护模式下运行
的编程方法。接着介绍了内核代码概况,给出了内核源代码目录树结构,
并依据该组织结构对所有内核程序和文件进行了详细描述和说明。为了加
深读者对内核工作原理的理解,书中最后一章给出了多个相关运行调试实
验。书中所有相关资料和信息均可从网站 www.oldlinux.org 下载。
本书适合作为高校计算机专业学生学习操作系统课程的辅助和实践教
材,也适合 Linux 爱好者作为学习内核工作原理的自学参考书籍,还可作
为一般技术人员开发嵌入式系统时的参考书。
作者简介
赵炯,工学博士,计算机专家,Intel公司访问学者,国际计算机仿真协会、上海市通信学会会员。研究方向为计算机通信。曾经为本科、硕士和博士研究生开设《计算机网络》、《计算机通信技术》、《计算机通信与工控网络》、《微型计算机》和《计算机原理》等课程。参与国家自然科学基金项目“系统芯片在线测试与容错技术研究”和上海市自然科学基金“基于节点主动控制的大规模复杂输送系统控制模型研究”等工作。
编辑推荐
适读人群 :计算机从业人员,计算机专业师生
赵炯博士的Linux内核源码书系列自从问世以来,在全国乃至世界范围内产生了很大影响。第一批读者受惠良多,早已成为IT大厂的中坚力量。多年过去了,Linux内核的体量发生了巨大变化,这更加凸显了“从小内核学起”的理念的正确。阅读本书,会帮助读者少走弯路,快速理解Linux的精髓,早日成长为合格的开发人员和系统架构师。
前言
本书是一本有关 Linux 操作系统内核基本工作原理的入门读物。
本书的主要目标
本书的主要目标是用尽量少的篇幅,对完整的 Linux 内核源代码进行解剖,使读者对操作
系统的基本功能和实际实现方式获得全方位的理解。
本书读者应是知晓 Linux 系统的一般使用方法或具有一定的编程基础,但比较缺乏阅读目
前最新内核源代码的基础知识,又急切希望能够进一步理解 UNIX 类操作系统内核工作原理和
实际代码实现的爱好者。这部分读者的水平应该介于初级与中级水平之间。目前,这部分读者
人数在 Linux 爱好者中所占的比例是很高的,而面向这部分读者以比较易懂和有效的手段讲解
内核的书籍资料不多。
现有书籍不足之处
目前已有的描述 Linux 内核的书籍,均尽量选用较新 Linux 内核版本(例如 Fedora 8 使用
的 2.6.24 稳定版等)进行描述,但由于目前 Linux 内核整个源代码的大小已经非常大(例如 2.2.20
版就已具有 268 万行代码!),因此这些书籍仅能对 Linux 内核源代码进行选择性或原理性的说
明,许多系统实现细节被忽略。因此并不能使读者对实际 Linux 内核产生清晰而完整的理解。
Scott Maxwell 的《Linux 内核源代码分析》基本上是面对 Linux 中、高级水平的读者,需
要较为全面的基础知识才能完全理解。而且可能是由于篇幅所限,该书并没有对所有 Linux 内
核代码进行注释,略去了很多内核实现细节,例如内核中使用的各个头文件(*.h)、生成内核
代码映像文件的工具程序、各个 make 文件的作用和实现等均没有涉及。因此对于处于初、中
级水平之间的读者来说阅读该书有些困难。
John Lions 的《莱昂氏 UNIX 源代码分析》虽然是一本优秀的学习 UNIX 类操作系统内核源代
码的著作,但是由于其采用的是 UNIX V6 版,其中系统调用等部分代码是用早已废弃的 PDP-11
系列机的汇编语言编制的,因此在阅读和理解与硬件部分相关的源代码时就会遇到较大的困难。
A. S. Tanenbaum 的《操作系统:设计与实现》是有关操作系统内核实现的优秀书籍,但该
书所叙述的 MINIX 系统是一种基于消息传递的内核实现机制,与 Linux 内核的实现有所区别。
因此在学习该书之后,并不能很顺利地即刻着手进一步学习较新的 Linux 内核源代码实现。
在使用这些书籍进行学习时会有一种“盲人摸象”的感觉,不容易真正理解 Linux 内核系
统具体实现的整体概念,尤其是对那些 Linux 系统初学者,或刚学会如何使用 Linux 系统的人
在使用那些书学习内核原理时,内核的整体运作结构并不能清晰地在脑海中形成。这在本人多
年的 Linux 内核学习过程中也深有体会。在 1991 年 10 月,Linux 的创始人 Linus Torvalds 在开
发出 Linux 0.03 版后写的一篇文章中也提到了同样的问题。在这篇题为《Linux--a Free unix-386
Kernel》
一 的文章中,他说:“开发 Linux 是为了那些操作系统爱好者和计算机科学系的学生使
用、学习和娱乐”。“自由软件基金会的 GNU Hurd 系统如果开发出来就已经显得太庞大而不适
合学习和理解”。而现今流行的 Linux 系统要比当年 GNU 的 Hurd 系统更为庞大和复杂,因此
同样也已经不适合作为操作系统初学者的入门学习起点。这也是作者基于 Linux 早期内核版本
写作本书的动机之一。
阅读早期内核的其他好处
目前,已经出现不少基于 Linux 早期内核而开发的专门用于嵌入式系统的内核版本,如 DJJ
的 x86 操作系统、?CLinux 等(在 www.linux.org 上有专门目录),也有许多人认识到通过早期
Linux 内核源代码学习的好处,目前国内也已经有人正在组织人力注释出版类似本书的书籍。
大家认为,通过阅读 Linux 早期内核版本的源代码,的确是学习 Linux 系统的一种行之有效的
途径,并且对研究和应用 Linux 嵌入式系统也有很大的帮助。
在对早期内核源代码的注释过程中,作者发现,早期内核源代码几乎就是目前所使用的较新内
核的一个精简版本。其中已经包括了目前新版本中几乎所有的基本功能原理的内容。正如《系统软
件:系统编程导论》一书的作者Leland L. Beck 在介绍系统程序以及操作系统设计时,引入了一种
极其简化的简单指令计算机(SIC)系统来说明所有系统程序的设计和实现原理,从而既避免了实
际计算机系统的复杂性,又能透彻地说明问题。这里选择 Linux 的早期内核版本作为学习对象,其
指导思想与 Leland 是一致的。这对 Linux 内核学习的入门者来说,是最理想的选择之一。
对于那些已经比较熟悉内核工作原理的人,为了能让自己在实际工作中对系统的实际运转
机制不产生一种空中楼阁的感觉,因此也有必要阅读内核源代码。
当然,使用早期内核作为学习的对象也有不足之处。所选用的 Linux 早期内核版本不支持
虚拟文件系统(VFS)和网络系统,也不包含对现有内核中复杂子系统的说明,而仅支持 a.out
执行文件。但本书是 Linux 内核工作机理实现的入门教材,因此这也正是选择早期内核版本的
优点之一。通过学习本书,可以为进一步学习这些高级内容打下坚实的基础。
阅读完整源代码的重要性和必要性
正如 Linux 系统的创始人在一篇新闻组投稿上所说的,要理解一个软件系统的真正运行机制,
一定要阅读其源代码。系统本身是一个完整的整体,具有很多看似不重要的细节,但是若忽略这些
细节,就会对整个系统的理解带来困难,并且不能真正了解一个实际系统的实现方法和手段。
虽然阅读一些操作系统原理经典书籍如 M. J. Bach 的《UNIX 操作系统设计》,能够对 UNIX
类操作系统的工作原理有一些了解,但实际上对操作系统的真正组成和内部关系实现的理解仍
不是很清晰。正如 Tanenbaum 所说的,“许多操作系统教材都是重理论而轻实践”,“多数书籍
和课程为调度算法耗费大量的时间和篇幅而完全忽略 I/O。其实,前者通常不足一页代码,而
后者往往要占到整个系统三分之一的代码总量。”内核中大量的重要细节均未提到。因此并不能
让读者理解一个真正的操作系统实现的奥妙所在。只有在详细阅读过完整的内核源代码之后,
才会对系统有一种豁然开朗的感觉,对整个系统的运作过程有深刻的理解。以后再选择最新的
或较新内核源代码进行学习时,也不会遇到大问题,基本上都能顺利地理解新代码的内容。
如何选择要阅读的内核代码版本
那么,如何选择既能达到上述要求,又不被太多的内容而搞乱头脑,学习效率又高的内核?作
者通过对大量内核版本进行比较和选择后,最终选择了与目前 Linux 内核基本功能较为相近,又非
常短小的 0.12 版内核作为入门学习的最佳版本。下图是对一些主要 Linux 内核版本行数的统计。
目前的 Linux 内核源代码量都在几百万行的数量上,2.6.0 版内核代码行数约为 592 万行,
极其庞大,对这些版本进行完全注释和说明几乎是不可能的。而 0.12 版内核不超过 2 万行代
码量,因此完全可以在一本书中解释和注释清楚。麻雀虽小,五脏俱全。为了对所研究的系
统有感性的了解,并能利用实验来加深对原理的理解,作者还专门重建了基于该内核的可运
行的 Linux 0.12 系统。由于其中含有 GNU gcc 编译环境,因此使用该系统也能做一些简单的
开发工作。
另外,使用该版本可以避免涉及较新内核版本中已经变得越来越复杂的各子系统(如 VFS、
ext2 或 ext3 文件系统、网络子系统、新的复杂的内存管理机制等)。
阅读本书需具备的基础知识
在阅读本书时,读者必须具备一些基本的 C 语言知识和 Intel CPU 汇编语言知识。有关 C
语言最佳的参考资料仍然是 Brian W. Kernighan 和 Dennis M. Ritchie 编写的 The C Programming
Language 一书。而汇编语言的资料则可以参考任意一本讲解与 Intel CPU 相关的汇编语言教材。
另外,还需要一些嵌入式汇编语言的资料。有关嵌入式汇编的权威信息都包含在 GNU gcc 编译
器手册中。也可以从 Internet 上搜索到一些有关嵌入式汇编的比较有价值的短文。本书中也包
含了一些关于嵌入式汇编的基本语法说明。
除此之外,还希望读者具备以下一些基础知识或者有相关的参考书籍在身边。其一是有关
80x86 处理器结构和编程的知识或资料。例如,可以从网上下载的 80x86 编程手册(80386
Programmer’s Reference Manual);其二是有关 80x86 硬件体系结构和接口编程的知识或资料(有
关这方面的资料很多);其三还应具备使用 Linux 系统的简单技能。
另外,由于 Linux 系统内核的实现最早是根据 M. J. Bach 的《UNIX 操作系统设计》一书的
基本原理开发的,源代码中许多变量或函数的名称都来自该书,因此在阅读本书时若能适当参
考该书,会更易于理解内核源代码。
Linus 在最初开发 Linux 操作系统时,参照了 MINIX 操作系统。例如,最初的 Linux 内核
版本完全照搬了 MINIX 1.0 文件系统。因此,在阅读本书时,Tanenbaum 的《操作系统:设计
与实现》也具有较大的参考价值。但 Tanenbaum 的书描述的是一种基于消息传递在内核各模块
之间进行通信(信息交换)的工作机制,这与 Linux 内核不一样,因此可以仅参考其中有关一
般操作系统工作原理章节和文件系统实现的内容。
使用早期版本是否过时
表面看来,本书对 Linux 早期内核版本注释的内容犹如 Linux 刚公布时 Tanenbaum 就认为
其已经过时(Linux is obsolete)的想法一样,但通过学习本书内容,你就会发现,利用本书学
习 Linux 内核,由于内核源代码量短小而精干,因此会有极高的学习效率,能够做到事半功倍,
快速入门。并且对进一步选择新内核部分源代码的学习打下坚实的基础。在学习完本书之后,
你将对系统的运作原理有一个非常完整而实际的概念。这种完整概念能使人很容易地进一步选
择和学习新内核源代码中的任何部分,而不需要再去啃读代码量巨大的新内核中完整的源代码。
Ext2 文件系统与 MINIX 文件系统
目前,Linux 系统上所使用的 Ext2(或最新的 Ext3)文件系统是在内核 1.x 之后开发的。
其功能详尽并且性能也非常稳定,是目前 Linux 操作系统上默认的标准文件系统。但是,作为
对 Linux 操作系统完整工作原理入门学习所使用的部分,原则上是越精简越好。为了对一个操
作系统有完整的理解,并且不受其中各子系统中复杂和过多的细节的干扰,在选择学习剖析用
的内核版本时,只要系统的部分代码内容能说明实际工作原理,就越简单越好。
Linux 内核 0.12 版仅包含最为简单的 MINIX 1.0 文件系统,对于理解一个操作系统中文件系
统的实际组成和工作原理已经足够。这也是选择 Linux 早期内核版本进行学习的主要原因之一。
在完整阅读本书之后,相信读者定会发出这样的感叹:对于 Linux 内核系统,我现在终
于入门了!此时,您应该有十分的把握去进一步学习最新 Linux 内核中各部分的工作原理和
过程了。
同济大学
赵炯 博士
目录
第 1 章 概述··············1
1.1 Linux 的诞生和发展···············1
1.1.1 UNIX 操作系统的诞生 ··········1
1.1.2 MINIX 操作系统 ················1
1.1.3 GNU 计划 ···················2
1.1.4 POSIX 标准 ··················2
1.1.5 Linux 操作系统的诞生 ···············3
1.1.6 Linux 操作系统版本的变迁 ················4
1.1.7 Linux 名称的由来 ················6
1.1.8 早期Linux 系统开发的主要贡献者 ········7
1.2 内容综述············································8
1.3 本章小结··········································12
第 2 章 微型计算机组成结构····················13
2.1 微型计算机组成原理·······················13
2.2 I/O 端口寻址和访问控制方式·········15
2.2.1 I/O 端口和寻址 ·······························15
2.2.2 接口访问控制 ·································17
2.3 主存储器、BIOS 和 CMOS存储器·································17
2.3.1 主存储器 ·······································17
2.3.2 基本输入/输出程序 BIOS ·················18
2.3.3 CMOS 存储器 ································19
2.4 控制器和控制卡·······························19
2.4.1 中断控制器 ····································19
2.4.2 DMA 控制器 ··································20
2.4.3 定时/计数器 ···································21
2.4.4 键盘控制器 ····································21
2.4.5 串行控制卡 ····································22
2.4.6 显示控制 ·······································24
2.4.7 软盘和硬盘控制器 ··························25
2.5 本章小结··········································28
第 3 章 内核编程语言和环境····················29
3.1 as86 汇编器······································29
3.1.1 as86 汇编语言语法 ··························30
3.1.2 as86 汇编语言程序 ··························31
3.1.3 as86 汇编语言程序的编译和链接 ·········33
3.1.4 as86 和 ld86 使用方法和选项 34
3.2 GNU as 汇编35
3.2.1 编译 as 汇编语言程序 36
3.2.2 as 汇编语法 37
3.2.3 指令语句、操作数和寻址 ·38
3.2.4 区与重定位 41
3.2.5 符号 43
3.2.6 as 汇编命令 44
3.2.7 编写 16 位代码 46
3.3 C 语言程序·47
3.3.3 圆括号中的组合语句 51
3.3.4 寄存器变量 52
3.3.5 内联函数 52
3.4 C 与汇编程序的相互调用54
3.4.1 C 函数调用机制
产品特色