Linux0.01内核基本上分析完了,高版本的内核也看了一点。有一点心得与大家分享
一下吧!这里我并不打算说具体的技术方面的东西,而是针对读内核的方法,谈谈自己
的一点感受。
我前段时间主要看的是0.01版本的内核。Linux0.01是Linux的"祖师爷"Linus完成的最早
的一个Linux版本,其内核编译后仅仅只有512K,麻雀虽小,五脏俱全,0.01包括了从软
盘启动、文件系统、控制台管理的操作系统完整功能,并提供了不少标准的用户接口,
具体有kernel, boot, fs, init,mm等几个部分,没有网络部分。
为什么选择Linux0.01?各位大虾一看到0.01肯定直摇头:哎呀,都什么时代的东东
了,有看的必要么?笔者当初选择0.01并没有太多的想法,只是Tm-linux小组刚开始选
择的是0.01,于是就开始读吧,现在仔细想想,读Linux0.01对于初学者来说可能更容易
上手些。可能有下面的几个好处吧
1)0.01的代码量较小。很多同学都曾有成为Linux高手的欲望,也曾抱回若干砖头书,但
Linux的发展何其之快,而coder又是黑客型高手,往往坚持不了多长时间而中途放弃!
2)0.01的代码简单而精简(这个简单当然是相对于后续版本而言的)。实际上0.01完成
的就是一个操作系统的最初的要求,包括启动,进程调度,内存管理等,而这些往往与
硬件结合,在看高版本的内核时往往还没有接触到这些硬件知识,层层下调已经把你搞
糊涂了。
3)从低版本看更能看到技术进步的源动力,比如0.01的内核很小,其启动代码可以只放
在一个扇区内,而后续版本的内核较大,无法放入一个扇区内,于是压缩核心的装入方
法诞生了。再如内存管理,0.01的内存管理比较简单,内存的申请释放直接通过使用前申请,
使用后释放,但考虑以后的版本功能复杂,如何解决可能的"外碎片"问题,如何解决内存不足的问题,于是对后续版本采用的"伙伴算法"
,slab技术,页面守护进程有更好的理解。
我说上面的这一些并非是为0.01做广告啦,而是提醒一下读内核可能遇到的问题:
比如说层次复杂难以理清,代码众多不知主次,哪些是操作系统必需的,那些是为提高系
统性能的等。
看内核的目的是什么,这是每个看内核的人都需要问问自己的问题。
我想对于大多数初看内核的人来说,最重要的是解决从操作系统原理到一个实际操
作
系统的过渡,简单一点说是操作系统到底是怎么跑起来的。操作系统原理大家都学了,但
一个操作系统到底是怎么启动的,所谓的保护模式到底是怎么一回事,进程调度和切换
到底是怎么进行的,一个文件系统具体应该怎样,可能很多还是模糊的。通过看Linux内
核,这些问题可以得到清晰的解答。
当然,一个有强大生命力的操作系统决不会仅仅满足于能跑起来,她采用的众多先进的
技术使得她有出色的性能,对于以后的工程设计、编程还有类Unix下的系统开发会有很
多帮助。
鉴于Linux的强大技术实力,在很多领域都会遇到跟其采用技术相关的,如嵌入式领域,
网络接口等等。理解了内核,当然在以后的开发中可以事半功倍。
我当初读内核的目的比较简单,我就是想看看Linux是怎么跑起来的,为什么多个进程可
以互不干扰的运行。
我读代码的工具是用的source insight,可惜不能自动识别汇编.s文件,而0.01汇编文
件不少。哦,讲了这么多,还没进入主题:我的体会心得啦
从哪部分开始读,一般读内核都建议从boot部分开始读,这样循序渐进,而且一般启动
部分似乎最神秘,最能满足好奇心啦!不过我是从memory部分开始读的,因为对逻辑地
址到物理地址的转换一直很模糊。从你感兴趣的地方开始读,在以后比较容易坚持。在读内核的方法上,我建议"先横后纵"。
在读内核的方法上,我建议"先横后纵"。
Souce insight的好处就是你点上某个函数,能自动显示该函数的定义,这样比较方便的
跳入察看。对于刚开始看内核的人,我并不太建议一开始用这种方法。因为函数层层嵌
套,等你下到最底层,早已忘了当初的调用的功能,建议只跳一层看看调用函数的注解
或者简单看看函数代码猜测功能,做一些记号。
我个人觉得,操作系同比较重要的是数据结构和算法,算法固然在程序中体现,而数据结
构需要查看相关的头文件及相关的文件才能了解。所以刚开始时我还是采用一个文件一
个文件的读,即所谓的"横",因为一个文件中的安排总是对特定的数据结构的一些操作
,你有更多的机会去理解各个主要数据结构的功能,包括结构中各个子项的含义。当然
不要忘了写注释啦(虽然现在的理解可能并不准确)。
在一个模块,如FS模块的各个文件都读完之后,就采用了所谓的"纵"了,你可以选择一
个比较重要的函数入手,进行层层跳入(或若干层)以领会各个数据结构间的有机关系
。如fs模块涉及的主要数据结构有:超级块,节点索引块,数据索引块,高速缓冲块,
文件等,在单独理解各个相关文件后,可以从do_execve入手,看一个文件从输入文件参
数到最后执行的主要步骤,进而理解VFS和具体fs之间的接口。
在每一个主要模块读完之后,最后自己写一份总结(书面总结啦),看看自己对这个模
块的把握。因为读代码往往是比较细致的,可能专注于读懂代码本身而忽略了模块的功
能和组织形式。这点我认为比较重要,所谓"牛吃草要反刍回味",读代码也许要在看完
之后进行总结,这样才能上升一个层次,真正理解其方法和结构的精妙之处。
最后,谈谈看Linux内核需要的一些基础吧
1) Intel386硬件知识,比如各寄存器,TSS,段描述表(IDT,GDT,LDT)等,段页转换
机制等(高版本的Linux支持其他硬件体系,但对intelx86的比较熟一些吧)
2) 汇编指令,尤其是AT&T语法及其迁入式汇编,当初我初次看到诸如 代码:
__asm__("std ; repne ; scasw\n\t"
"jne 1f\n\t" "movw $1,2(%%edi)\n\t"
"movw $1,2(%%edi)\n\t"
"sall $12,%%ecx\n\t"
"movl %%ecx,%%edx\n\t"
"addl %2,%%edx\n\t"
"movl $1024,%%ecx\n\t"
"leal 4092(%%edx),%%edi\n\t"
"rep ; stosl\n\t"
"movl %%edx,%%eax\n"
"1:"
:"=a" (__res)
:"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES),
"D" (mem_map+PAGING_PAGES-1)
:"di","cx","dx");
这样的一条汇编语句感到头脑发胀,不过了解其格式后,多看就习惯了。
3) 操作系统的基本知识,对于操作系统的一般理解,这个大家都有吧!
4) 一本或几本Linux内核的参考书,有参考书总要好得多,毕竟很多数据结构不用自己
去猜,我在读0。01感觉有很大不同,很多地方只能猜,不过还是有用的。至于Linux内
核的书已经很多了,到都乐去看看就知道了
5) 恒心+毅力:这是最重要的一点,初始的兴趣往往会被遇到的困难一扫而光,再加上
其他杂七杂八的事情,坚持确实很困难。当初Tm-linux组刚开始参加内核分析的人不下
几十,但坚持到底的也就寥寥数人(这只是0.01哦)
6) 跟别人多多交流,毕竟个人能力有限,通过交流,可以增进知识,我很鼓励书面的
交流,虽然可能需要花费一些时间来写,因为书面的东西以后可查,而书面的跟别人交
流总希望正确一点,少犯错误啦。这一点西安交大做得比较好,组织了Linux内核论坛,
隔一段时间聚会交流一次,每次有一主题,先有人主讲,然后大家互相讨论。
这些你有些没有吗,那么恭喜你啦,因为通过读内核你就可以增加这方面的知识和经验
了。
读内核也不是最终目的,对自己在嵌入式系统的开发,或Linux的"运用自如",或者实现
自己的操作系统,那才是"剑出鞘时"!
估计成电读Linux内核的人不少,只是大家交流比较少,我想交流还是很重要的,虽然牛
人从来都不是问出来的,但具体问题通过交流可以增加理解,提高认识。很愿意也鼓励
大家通过各种方式交流,虽然我不是大牛(也不是小牛啦J),很愿意通过bbs,Email,
或其他方式进行交流。
罗嗦了这么多,希望自己的一点见解能对大家有所启发,也希望成电涌现更多的Linux牛人啦!