经过之前的摸索,对Linux内核的学习有一些自己的看法,就列一下自己支持的学习方法:
1、要选最新的内核去学。Linux内核版本变化太快了。Linux 0.11就是一个自己动手写操作系统的范例,而到Linux 2.4则发展到百万行级,被移植到各种平台。到2.6呢,Linux在这个版本停留最久,小的版本差异,整个子系统完全不同。就我所知,在2.6中,devfs被废弃,sysfs新加入,usb支持到3.0,整个内核支持内核态抢占,等等。即使你学会了2.4,那也是一个和2.6相差很大的系统。何况内核的变化,也反映了硬件平台的巨大变化。有SMP多核、APIC、ACPI电源管理、PCI、PCI Express总线、PCH芯片组,缓存一致性、大内存支持等等,这中间的变化太大了。而且,Linux经历2.6的风风雨雨,各个子系统都逐渐成熟,模块结构更加合理,你会看到最优秀的系统设计,尽管也是最庞大的。综上所述,要学就要选最新的,但这也并非一定要选3.0,选2.6中版本靠前的即可,推荐2.6.32以上的。
2、从设备驱动入手。Linux内核就像一个大铁球,往往找不到地方下嘴。Linux内核中动辄几万行的子系统,内存管理、线程管理、定时器、信号量临界区,等等内容耦合在一起,各种gcc的特殊用法,为了性能而极其复杂的代码,被滥用的宏定义,为支持多种硬件平台而抽象到极致的层层封装...... 最为一个学习用的内核,Linux真是糟透了。幸好它还给我们留了一丝光亮,就是设备驱动。最简单的字符设备驱动可以只有几百行代码,绝对看得懂,而较为复杂的usb驱动则达到31万行代码,更不要提被过分优化的块设备驱动了。设备驱动足以为我们提供一个入口点,写一个模块,让它在内核中跑起来。但要记住,这只是起点。
3、进阶-从看代码说起。如果你只会照葫芦画瓢地写一些幼稚的字符设备驱动,你一定不敢对人说你对Linux内核如何如何。学习一个东西,最基本的要求就是能看懂它。遗憾的是,系统往往用起来简单,学起来难;内核API容易调,但却渗入不到核心的地方去。这是就必须找一条进阶之路—那就是能看到、接触、学习Linux代码。这个代码量不能太大,但也不能太小,与其它模块耦合度尽量低,最好能动手试一试。我觉得usb驱动是个不错的选择。虽然如此,看设备驱动都有一个不可避免的问题,就是对设备的认识程度直接决定你对相应代码的理解程度。usb不是核心设备,规范也比较清晰,但它的工作方式过于复杂,驱动的层次划分至少三层,很有挑战性。
4、进阶-从写代码说起。虽然看Linux代码是个很有挑战性、很锻炼思维的事情,但它却无助于你写代码能力的提高。往往你看懂八成,理解五成,融会贯通三成,能用出来的也只剩一成。但就这一成,也要往死里用才行。我发现只写简单的驱动,无济于事;看比较复杂的驱动,好像看得挺热闹,却掺和不进去。所以学Linux绝非只看看就能了事。要写代码,要修改代码。要学习的就不只是驱动本身,而是整个Linux内核提供的编程环境。包括内存管理、线程管理、定时器 、临界区、信号量、工作队列等等,许多东西来支持设备驱动。你不学这些东西,就改不了驱动,写代码也就无从谈起。其实这些东西本身并不复杂,只是比较零散,你看驱动时很容易看懂,却不注意,到时也用不出来。只要拿些例子练练,从驱动中看到的多拿出来用,慢慢就积累起来了。
5、目标。操作系统的根本目的是管理硬件资源和提供用户服务。我想,当我们能把目光专注于硬件,不再为写驱动而写驱动时,就真的是学有所得了。而对Linux内核有所创新,对内核算法有所改进,那还不是我所能眺望到的。