学习linux的理想方法:先有对linux内核体系的全局视野,然后将子系统一一攻破,实践验证系统调用,最后上开发板移植内核
1.首先建立起内核的大体框架
目的:
理解各个子系统的设计理念和构建思想,这些理念和思想会从宏观上呈献给你清晰的脉络,就像一个去除了枝枝叶叶的大树的主干,一目了然
初步建立起内核子系统框架和代码实现之间的关联: 看到某个函数名就知道其针对哪个子系统、实现什么功能
不要一开始就深入细节导致串联各个子系统,导致注意力分散。
- 具体如何学习?(自上而下, 理解概念和框架)
1.交叉读书:
1.先看LKD3,专于一个子系统,主要就是了解设计的原理和思想
2.再看ULK3和PLKA上看同样的子系统,但是并不仔细分析底层具体函数的代码,只是粗略地、不求甚解地看,甚至不看
2.把不理解的地方都记录下来
- 按顺序学习时,后面的内容会引用前面的,需要不时回头看看
子系统进行管理工作需要大量的数据结构,不要纠结于一个不理解的点上,暂且放过,回头还可以看的
2. 然后选择一个子系统学习
比如驱动、网络,或者文件系统之类的。这个时候你再去深入了解底层代码实现,相较于一开始就钻研代码,更容易一些,而且碰到了不解之处,或者忘记了某个方面的实现,此时你完全可以找到相应的子系统,因为你知道在哪去找,查漏补缺,不仅完成了对当前函数的钻研,而且可以回顾、温习以前的内容,融会贯通的时机就在这里了
3. 动手写代码
实践是第一位的,实践就是知道的过程,实践产生经验,经验的总结就是理论,理论源于实践,理论才需要理解
纸上得来终觉浅,绝知此事要躬行。只看书是绝对不行的,一定要结合课本给出的编程建议自己敲代码。刚开始就以模块形式测试好了,或者自己编译一个开发版本的内核。一台机器的话,使用UML方式(User Mode Linux)调试,内核控制路走到哪一步,单步调试看看程序执行过程,比书上的讲解更直观明了。一定要动手实际操作。
4. linux学习的几个阶段
阶段1
已经在 Linux平台上工作或者学习了很久,至少大多数 Shell命令用的还可以,对 Linux这个黑盒子已经有了自己的感觉和理解
阶段2
1.能够熟练和准确的运用 C 语言的语法和技巧,熟悉 GCC 的一些特性,一些更深入的要求是能够研究一些 glibc 库函数的实现,这样会帮助你对神秘的glibc有实际的理解,与此同时它能使你养成严谨代码的写法。
2.了解一些编译器的用法,如果是嵌入式开发,那么这是必须的:
首先了解这些选项的作用和优化的原理,在此基础上了解GCC编译的整个过程:预处理,汇编以及链接。更深一步的要求是对链接器的原理,ELF文件的构造和特定CPU架构的汇编语言有正确的理解和全局的把握。
3.第三点就是在这个阶段编程时尽量广泛的使用Linux上不同应用的系统调用:
文件操作:读写,链接,权限控制,文件锁。
进程间通信:信号,管道,套接字。
网络应用:TCP/IP,UDP,RAW Socket,NETLINK 等。
多进程和线程的应用等。
其中进程间通信和网络应用是Linux的精华所在,如果错过了它们,可以说是一很大的遗憾。
在第二个阶段完成的代码量至少要几万行,并且它们最终看起来和开源项目的代码间没有明显的区别
在这段时间形成自己的经验代码,最好形成一个或者几个库:针对网络的,文件操作的,锁机制的,进程间通信的等等!库中的代码应该清晰明了,和标准的函数 库没有本质的区别,你可以熟练引用这些库函数来实现应用并能大概讲清楚它实现的流程
阶段3
- 准备一块开发板
拥有该开发板的所有软硬件资料,其中包 含Bootloader和 Linux内核的源码,电路图,芯片文档。这保证你不会形而上学的在那猜测, 然后似是而非的理解
- 选择你喜欢的或者工作需要的内核版本
应该选择Linux2.6.11或者更高2.6.24版本
5.区分共性与平台特性
- 中断响应是共性,8259 中断控制器和 IDT 是 x86 的特性。
- 虚拟内存管理是共性,x86 的 GDT 和 LDT 是特性,而且现在的系统也只是走个过场而已。
- 任务调度与上下文切换是共性,x86 的 TSS 是特性,而且现在的系统(2.2.0 以后)也不用 TSS 做任务切换了,早期的 Linux 是用了 TSS 的,读老代码的时候要注意。
- IO 是共性,位于 0xB8000 的显示缓冲区是 x86 的特性。
- 系统初始化是共性,BIOS 把引导扇区加载到 0x7C00 是 x86 的特性。国内好多书对 PC 的系统引导过程(booting)大书特书,是主次不分、本末倒置,你学的是操作系统,不是 boot loader 。
6.书籍
以下三本书会对linux的同一个问题的不同角度的描述:
LKD3: Linux.Kernel.Development.3rd.Edition
偏向说明设计的原理和思想
PLKA: professional linux kernel architecture
介于LKD3和ULK3之间,对函数的仔细讲解都做补充说明,去掉函数体中边边角角的情况,比如一些特殊情况的处理,有效性检查等,而不妨碍对整个函数体功能的理解
ULK3: Understanding.the.Linux.Kernel.3rd.Edition
偏向对支持该原理和思想的主要函数实现的具体分析
Intel V3
针对X86的CPU,本书自然是系统编程的权威。内核部分实现都可以在本书找到其根源。
在读以上三本书某个子系统的时候,不要忘记可以在V3中相应章节找到一些基础性支撑信息
LDD3: Linux.Device.Drivers.3rd.Edition
linux驱动设计