Linux是开源的操作系统,其系统所有源代码都是开放的,这对研究操作系统是十分方便的。
Linux内核发展至今,版本特别多,比较经典的是2.6内核。所以本文以研究 2.6内核为主。可是内核比较大,从哪里入手是一个十分重要的问题。显然,一开始就看内核源代码是不切实际的,是可能被细节搞晕的。在计算机专业的课程中我们都学习过操作系统课程,对操作系统的大概功能有所了解,而那些linux内核的书也对linux内核框架作了整体上的介绍,这些都是基础知识。也许我们没有时间去研究清楚操作系统的每一个细节,但是我们却可以研究我们感兴趣的部分。
面对内核源码,最直接的一个问题就是如何编译内核,如何安装新内核到系统中? 内核编译安装好后, 就可以加载运行了。而grub是如何加载内核的?grub是怎么实现的?elf文件格式是什么样的?进而引出程序的编译、链接、加载等问题。研究一个开源程序的方法之一就是跟踪调试程序,然而内核不是一般程序,不能直接调试,因此需要搭建内核调试环境。
操作系统分为进程管理、内存管理、设备管理、文件系统、网络等部分,针对某一模块学习时,又会提出更多的问题。研究某一确定模块时,可以假定其他模块是已知的,而不必要陷入其他模块的细节中去。
研究内核的深度也各有不同,有以下四 级别:
- 只看操作系统相关书藉,了解其原理,不看源码。
- 在源码中能找到对应模块的实现,了解部分技巧与细节。
- 可以修改源码以实现自己想要的功能。
- 可以在内核中实现一套独立的系统。
自顶向下的研究内核:
如进程管理这一部分,本打算从CPU加电起到进程相关数据结构初始化,进程创建,进程调度这样一步步研究,结果发现在对源码一无所知的情况下,看进程初始化,又陷入了中断、文件系统、内存的初始化细节中。所以打算从进程调度 进程创建开始研究。
另外,程序=数据结构+算法。
先研究数据结构(task_struct)中各字段的作用,再研究调度算法,并分析对应源代码,从宏观上把握进程调度框架,再从细节上逐步深究。
现在内核大多使用面向对象的思想,可以从对象的角度考虑问题。
内核代码较多,搞清楚内核代码组织的结构和原理。
内核设计思考:
为什么这么设计? 考虑了哪些因素? 有什么要求?
怎么设计? 这样设计有什么好处和坏处?
内核中的数据结构之间的关系:
同种数据结构之间如何组织?(树,链表,有个链表的初始化的头结点)
不同数据结构之间的关系?指针指向?用个数字标识符,然后用hash表关联数字与指针?
阅读源码的工具
内核源码
GDB GDBTUI DDD跟踪 source insight
SystemTap stap kdb
静态阅读
修改源码验证一些问题
写一些应用
下面是Linux操作系统整体架构(图片来源于国嵌PPT中)
Linux内核架构