Linux内核(15) - 方法论
什么是方法论
方法论给人的第一感觉就是它是一个玄之又玄的很朦胧的东西,显然,学习本身就是一件很玄乎的事情,有些人整天潇潇洒洒没见怎么用心就能够获得很好的成绩,而有些人则相反,投悬梁锥刺骨也还是成绩平平收获平平。这里面很大一部分的原因就是方法论。
当然因为每个人的情况并不相同,也就没有这样一个标准的方法论存在,所以说起来就很容易成为一场大忽悠。就像任志强先生前阵子做卖房方法论的演讲时,因为太像一场忽悠,就被听众扔了鞋。
那么什么是方法论?很多人都应该会很自然的回答方法论就是方法,这也没错,那么这里为什么要使用方法论这个词,不是我非要在这里故弄玄虚,这都要怪笛卡儿在17世纪的某一天,闲极无聊写了这么一本书,书名就叫《方法论》,在这本目前来说绝大部分人都不知道的书里将方法上升到了理论的高度,于是就有了方法论。
这本书无形中影响了一代又一代人,比如今天的凤姐,如果以后有一天凤姐出了回忆录,我们去研究她光辉的成名之路时,就会发现,方法论对她以及她后面的团队的巨大影响。因此说方法论对于成就一件事情来说是很重要的,对于我们的内核学习也是如此。
笛卡儿在他的书里将方法论,也就是研究问题的方法归纳为简单的一句话,就是“复杂问题要简单化”。就是说要将复杂的问题分解为很多个简单的小问题,一个个的分开解决。这句话当然可以借鉴运用到内核的学习上,不过需要做些改动,不是分解为多个简单的小问题,而是将内核学习这么一件很复杂的事情划分为由低到高多个不同的层次,每一层次都有自己需要达到的目标和要求。这也是我自己认为的内核学习的方法论,也就是认识内核的方法。
认识内核:内核的基本面
学内核最好把它看成一个鲜活的生命体,而不仅仅是一堆死气沉沉的代码。具体一点来说,我们在学习与浏览内核的实现时,可以将它看成是现实世界的映射。内核是由现实中的人写出来的,因此不管是有意还是无意,都会不可避免的包含了一些自己的现实感情,我们研究内核时可以体会下这种脉络,这种隐藏在代码背后的哲学。比如,我们可以认为内核是个大世界,一个个进程就是这个世界中的一个个生命体,进程管理和调度就是这个大世界中的权力机关,内存是进程的家,内核的目标就是要做到使每个进程都居者有其屋。
既然要把内核看成是一个鲜活的个体,那么我们认识它的第一件事就是了解它的一些基本信息,就像我们人与人之间互相认识首先也是通过个人的基本信息一样。
首先从名字开始,kernel在字典中主要有两种定义,一种是“软的,一个坚果可食用的部分”,对Linux kernel来说,当然适用的是第二种定义:“某个东西的核心部分”。所以从广义上来说,linux kernel就是linux操作系统里最为核心的部分,而从狭义上来说,它不过就是Linus那群人人写的那点儿代码。
当然,这点儿代码是相当复杂的,单单从代码量上来说,早已经突破了千万级。从结构上来说,也早就不是一个人穷自己一己之力就能够全部理解的了。所以,学内核切忌求大求全,选择一点研究的足够深入就很不容易了。
然后是kernel的年龄,kernel又不是一个怀春的少女,所以它的年龄并不需要保密,从1991年诞生开始,在去年刚刚举行了它自己的成人礼,进入了成熟发展期。
就像我们人有自己的青春期、中年期等一样,kernel相应的也有很多不同的版本号,不过不同的是,我们的青春期一去就不复返了,kernel不同的版本号却是共存的。
很多年以来,内核的版本都是以X.Y.Z这3个数字的形式分配的,中间的偶数Y代表稳定版,奇数Y代表了不稳定的开发版。所谓的稳定版本是指内核的特性都已经固定,代码运行稳定可靠,不会再增加新的特性,要改进也只是修改代码中的错误。而不稳定版本是指相对于上一个稳定版本增加了新的特性,还处于发展之中,代码的运行不大可靠。
对于目前来说,2.6内核的发布已经持续了很长时间,那么什么时候将会推出2.7?Linus本人的回答是,不会有2.7,他不会再遵循旧的模式,新采用的模式会更好,不值得重复过去。他表示正在考虑新的编号方式,一种基于时间的版本号。比如用2008.7取代2.6.26,中间第二个数字代表年,2008年就是2.8,2009年的第一个版本就是2.9.1,之后2010年是3.0,等等。
最后不得不提到是那些眼花缭乱的发行版,内核与发行版的关系就类似那种双生花,彼此互相依赖互相扶持共同成长。没有那些发行版,内核就只能是束之高阁的一个貌似好看的玩具,并不能真正的走进我们的工作生活,而没有内核,那些发行版就缺少了存在的地基,就只能是个豆腐渣工程。所以学内核前首先要会用linux,不能轻视发行版的使用。
认识内核:内核的内涵
认识了内核的外表之后,就需要认识内核的内涵,也就是内核的体系结构。
首先看第一张图,它向我们传递了这样的信息——内核将应用程序和硬件分离开来。内核一方面负责与计算机硬件进行交互,实现对硬件的控制,调度对硬件资源的访问,另一方面为用户应用程序提供一个高级的执行环境和访问硬件的虚拟接口。
提供硬件的兼容性是内核的设计目标之一,几乎所有的硬件,只要不是为其他操作系统所定制的,都可以得到Linux的支持。
与硬件兼容性相关的是可移植性,也就是在不同的硬件平台上运行Linux的能力。从最初只支持标准IBM兼容机上的Intel X86架构到现在可以支持ARM、MIPS、PowerPC等几乎所有硬件平台,如此广泛的平台支持之所以能够成功,部分原因在于,内核清晰地划分为了体系相关部分和体系无关部分。因此也就有了第二张图。
体系无关部分通常会定义与体系相关部分的接口,这样,内核向新的体系结构移植的过程就变成确认这些接口的特性并将它们加以实现的过程。
同时,用户应用程序和内核之间的联系,一般是通过它和内核的中间层——标准C库来实现,而标准C库函数本身,则是建立在内核提供的系统调用基础之上。通过标准C库,以及内核体系无关部分与体系相关部分的接口,用户应用程序和部分内核都成为可移植的。
因此更为准确的是第三张图。其中,进程管理部分实现了一个进程世界的抽象,这个进程世界类似于我们的人类世界,只不过我们的世界里的个体是人,而在进程世界里则是一个一个的进程,我们人与人之间通过书信、手机、网络等交通往来,而各个进程之间则是通过不同方式的进程间通信,我们所有人都在分享同一个地球,而所有进程都在分享一个或多个CPU。
在这个进程的世界里,内存是重要的资源之一,就好似我们的土地。因此,管理内存的策略与方式,也就是内存管理是决定系统性能的一个关键因素。