Linux内核源码分析方法

所需积分/C币:10 2015-03-17 22:43:56 625KB PDF
3
收藏 收藏
举报

这是一篇比较好的文章,我整理出来,免费供大家下载学习。
内核源码难不难? 从本质上讲,分析 Linux内核代码和看别人的代码没有什么两样,因为摆在你面前的一般都不是你自己写出来的代码。我们先举一个简单的例子, 一个陌生人随便给你一个程序,并要你看完源码后讲解一下程序的功能的设计,我想很多自我感觉编程能力还可以的人背定觉得这没什么,只要我耐心 的把他的代码从头到尾看完,肯定能找到答案,并且事实确实是如此。那么现在换一个假设,如果这个人是 Linus,给你的就是Liuⅹ内核的一个模块的 代码,你还会觉得依然那么轻松吗?不少人可能会有所犹豫。同样是陌生人( Linus要是认识你的话当然不算,呵呵~)给你的代码,为什么给我们的感 觉大相径庭呢?我觉得有以下原因 Linux内核代码在“外界”看来多少有些神秘感,而且它很庞大,猛地摆在面前可能感觉无法下 手 比如可能米源于一个很细小的原因—找不到main函数。对于简单的demo程序,我们可以从头至尾的分析代码的含义,但是分析内核代码这招就 彻底失效了,因为没有人能把 Linux代码从头到尾看上一遍(因为确实没有必要,用到时看就可以了)。 2.不少人也接触过大型软件的代码,但多数属于应用型项目,代码的形式和含义都和自己常接触的 业务逻辑相关。 而内核代码不同,它处理的信息多数和计算机底层密切相关。比如操作系统、编译器、汇编、体系结构等相关的知识的欠缺,也会让阅读内核代码 障碍重重 分析内核代码的方法不够合理。面对大量的并且复杂的内核代码,如果不从全局的角度入手,很 容易陷入代码细节的泥淖中。 内核代码虽然庞人,但是它也有它的设计原则和架构,否则维护它对仼何人来说都是一个噩梦!如果我们理淸代码模块的整体设计思路,再去分析 代码的实现,可能分析源码就是一件轻松快乐的事情了。 针对这些问题,我个人是这样理解的。如果没有接触过大型软件项目,可能分析Linⅸ内核代码是一个很好的积累大型项目经验的机会(确实, Iinuⅹ代码是我目前接触到的最大的项目了!)。如果你对计算机底层了解的不够透彻,那么我们可以选择边分析边学习的方式去积累底层的知识。可 能刚开始分析代码的进度会稍显迟缓,但是随着知识的不断积累,我们对 Linux内核的“业务逻辑”会逐渐明朗起来。最后一点,如何从仝局的角度把 握分析的源似,这也是我想与大家分享的经验 、内核源码分析方法 第一步:资料搜集 从人认识新事物的角度来讲,在探索事物本质之前,必须有一个了解新鲜事物的过程,这个过程是的我们对新鲜事物产生一个初步的概念。比如我 们想学习钢琴,那么我们需要先了解弹奏钢琴需要我们学习基本的乐理、简谱、五线谱等基础知识,然后学习钢琴弹奏的技巧和指法,最后才能真正的 开始练习钢琴。 分析内核代码也是如此,首先我们需要定位要分析的代码涉及的内容。是进程同步和调度的代码,是内存管理的代码,还是设备管理的代码,还是 系统启动的代码等等。内核的厐大决定着我们不能一次性将内核代码全部分析完成,因此我们需要给自己一个合理的分工。正如算法设计告诉我们的, 要解决一个大问题,首先要解决它所涉及的子问题。 定位好要分析的代码范围,我们就可以动用手头的一切资源,尽可能的全面了解该部分代码的整体结构和大致功能 搜索引擎 文档注释 专业书籍 资料搜集 经验积累 源码标识符 这里所说的一切资源是指尢论是 Baidu、(ogle大型內络搜索引擎,还是操作系统原理教材和专业书籍,亦或是他人提供的经验和资料,甚全是 Linux源码提供的文档、注释和源码标识符的名称(不要小看代码中的标识符的命名,有吋它们能提供关键的信息)。总之这里的一切资源指的就是你 能想到的一切可用资源。当然,我们不太可能通过这种形式的信息搜集获得所有的我们想要的信息,我们只求尽可能全面即可。因为信息搜集的越全 面,之后分析代码的过程能使用的信息就更多,分析过程的困难就会越小。 这里举一个简单的例子,假定我们要分析 Linux的变频机制实现的代码。目前为止我们仅仅是知道这个名词而已,透过字面含义我们可以大致猜测 它应该和CPU的频率调节相关。通过信息搜集,我们应该能得到如下的相关的信息 1. CPUFreq机制。 2. performance、 powersave、 userspace、 ondemand、 conservative调频策略。 3./driver/cpufreq/ documention/cputrcq 5. P state和 C state 分析Linπx内核代码如果能搜集到这些信息,应该说是非常“幸运”了。毕竟有关 Linux内核的资料确实不如NET和 JQuery那么丰富,不过这相 比于十数年前,没有强大的搜索引擎,没有相关的研究资料的时期应该称得上是“人丰收”时代了!我们通过简单的“搜索”(可能公花费一到两天的 时间吧),甚全找到∫这部分代所在的源码文件目录,不得个说这样的信息简直是“价值连城”! 第二步:源码定位 从资料搜集中,我们“有幸”找到了源码相关的源码目录。但是这并非意味着我们的确就是分析这个目录下的源代码。有时我们找到的目录有可能 是分散的,也有时我们找到的目录下有很多和具体机器相关的代码,而我们更关心的是待分析代码的主要机制,而非与机器相关的特化代码(这样更有 助于我们理解内核的本质)。因屺,我们需要对资料中涉及代码文件的资料进行仔细甄选。当然,这一步也不太可能一次性完成,谁也不能保证一次就 能选择岀所有待分析的源码文件而且一个不漏。但是我们也不必担心,只要我们能抓住大多数模块相关的核心源文件,通过后期对代码的具体分析,就 很自然的把亡们全部找出来 回到上述的例子中,我们认真的阅读/ documention/cpufreq下的文档说明。目前的 Linux源码会把模块相关的文档说明保存在源码目录的 documention 的文件夹下,如果待分析的模块没有文档说明,这多少会增加定位关键源码文件的难度,但是不会导致我们找不到我们要分析的源码。通过阅读文档说 明,我们至少能关注到 driver/cpufreq/cpufreq. c这个源文件。通过这个对源文件的文档说明,结合之前搜罗到的调频策略,我们很容易关注到 cpufrcq performancec、 cpufrcq powcrsavc c、 cpufrcq userspace.c、 cpufrcq ondemand、 cpufrcq conservative.c这五个源文件。所有涉及的文件都找完了 吗?不用担心,从它们开始分析,迟早能找到其他的源文件。如果在 windows下使用 sourceinsight阅读内核源码的话,我们通过函数的调用和查找符号 引用等功能,结合代码的分析可以很方便的找到另外的文件 freq table.c、 cpufreq stats.c和/ include/linux/cpufreq. h。 cpufreg . c cpufreq performance. c cpufreg userspace c cpufreq conservative. c cpufreq powersave. c cpufreq ondemand.c cpufreq stats.c cpufreg. h freq table.c 按照搜索出的信恳流动方向,我们完全可以定位到需要分析的源码文件。源码定位这一步并非|分关键,因为我们不需要找出所有源码文件,我们可 以把部分工作推迟到分析代码的过程中。源码定位也比较关键,找到一部分源码文件是分析源码的基础 第三步:简单注释 在已定位好的源码文件中,分析每个变量、宏、函数、结构体等代码元素的大致含义和功能。之所以称此为简单注释,并非指这部分的注释工作很简 单,而是指这部分的注释可以不必过分细化,只要大致描述出相关代码元素的含义即可。相反,这里的工作其实是整个分析流程中最困难的一步。因为这 是第一次深入到内核代码的内部,尤其是对于首次分析内核源码的人来说,大量的生疏GNU的C语法和铺天盖地的宏定义会令人很绝望。此时只要沉下 心来,弄清每个关键的难点,才能保证以后碰到类似的难点不会再被困住。而且,我们对内核相关的其他知识会不断的像树一样扩展开来。 比如在 putre.c文件开始就会岀现“ DEFINE_ PER CPU”宏的使用,我们通过查阋资料可以基本卉清这个宏的含义和功能。这里使用的于段和之前 搜集资料使用的方法基木一致,另外我们也可以使用 sourceinsight提供的转到定义等功能查看它的定义,或者使用LKML( Linux Kernel mail list)查阅, 实在不行我们还可以到www.stackoverflow.con提问寻求解答(想了解什么是LKML和stackoverflow?搜集资料吧!)。总之利用所有可能的手段,我们总 能得到这个宏的含义一一为每个CPU定义一个独立使用的变量。 我们也不要强求一次能把注释描述的很准确(我们甚至都没必要弄清每个函数的具体实现流程,只要弄清大致功能含义即可),我们结合搜集到的 资料和后边代码的分析不断的完善注释的含义(源码中原有的注释和标识符命名在此很有利用价值)。通过不断的注释,不断的查阅资料,不断的修改注 释的含义 对代码的初步了解 代码元素注释 查阅难点资料 注释含义修正 当我们把所有涉及的源码文件简单注释完毕后我们可以达到如下效果: 基本卉清了源码中代码元素存在的含义 2.找出了该模块所涉及的基木上全部的关键源码文件。 结合之前搜集到的信息和资料对该待分析代码的整体或者架构描述,我们可以将分析的结果和资料对比,以确定和修正我们对代码的理解。这样, 过一遍的简单注释,我们就可以从整体上把握了源码模块的主要结构ε这也达到了我们简单注释的基本目的, 第四步:详细注释 完成代码的简单注释后,可以认为对模块的分析工作完成了一半了,剩下的内容就是对代码的深入分析和彻底理解。简单注释总是个能将代似元素的 具体含义描述的十分精确,因此详细注释是十分有必要的。这一步中,我们需要弄清以下内容: 1.变量定义在何时被使用。 2.宏定义的代码何时被使用。 3.函数的参数和返回值的含义。 4.函数的执行流程和调用关系。 5.结构体字段的具体含义和使用条件。 我们甚至可以把这一步称为函数详细注释,因为函数之外的代码元素的含义基本上在简单注释中已经比较明确了。而函数本身的执行流稈、算法等是 这部分注秤和分析的主要任务 比如 cpufreq ondemand策略的实现算法(函数 dbs check cpu中)是如何实现的。我们需要逐步分析该函数使用的变量和调用的函数等信息,弄清算 法的来龙去脉。最好的结果,我们需要这些复杂函数的执行流程图和函数调用关系图,这是最直观的表达方式

...展开详情
试读 17P Linux内核源码分析方法
立即下载 低至0.43元/次 身份认证VIP会员低至7折
一个资源只可评论一次,评论内容不能少于5个字
您会向同学/朋友/同事推荐我们的CSDN下载吗?
谢谢参与!您的真实评价是我们改进的动力~
  • 签到新秀

关注 私信
上传资源赚钱or赚积分
最新推荐
Linux内核源码分析方法 10积分/C币 立即下载
1/17
Linux内核源码分析方法第1页
Linux内核源码分析方法第2页
Linux内核源码分析方法第3页
Linux内核源码分析方法第4页

试读结束, 可继续读2页

10积分/C币 立即下载 >