Linux内核“问题门” - 学习问题、经验集锦

陈宪章说:“学贵有疑,小疑则小进,大疑则大进。疑者,觉悟之机也,一番觉悟一番长进。”

培根说:“多问的人将多得。”

还在学校的时候导师在激情讲演之后对着会议室里形态各异但均静默不语的我们痛心疾首的说:“会提问题很重要啊,同志们!不会提问题怎么有资格做研究!”

这样铿锵有力的训诫今日想起仍觉深受刺激,于是就要不可避免得要做出一些反应来。不过一是因为咱这年代还没有非主流的说法,二是因为也没有冯仰妍同学的性别优势,不可能受到刺激就整出个门来。咱能够做到的最大反应也就是在这里开贴专门探讨探讨内核学习的相关问题,为了稍微增加那么一些广告效应,就称为“问题门”吧。

使用“问题门”的称呼,一是内心里潜藏的那点低级趣味想去沾点近些年层出不穷各种各样的“门”的仙气,二是在内核的学习过程中的确实实在在的存在着这样的一个“门”,横亘在我们的面前,跨过去便海阔天空是另一番世界,但却是让无数人竞折腰,百思不得其钥匙。

另外,这个“问题门”也算是为拙作《Linux内核修炼之道》制作的一个小插曲,以感谢精华篇发布过程中很多朋友的关心与支持,希望通过对大家内核学习过程中遇到的问题与经验心得做一番展示,来帮助还在门外的朋友寻找到这扇门的钥匙。

我先对网友提出最多的问题进行解答,“抛砖引玉”,来作为这个“问题门”的雏形,大家也可以在评论里提出自己的问题和分享自己的学习心得,我会及时地对其进行整理汇总,大家一起将“问题门”逐步完善,帮助后来者和有需要地人不再为“入门”而苦恼。你的问题可能被收录到我的新书中! 希望这是一篇能够成长得文章!

提出你的问题,不要“陪公子读书”,祝早日“入门”!

2010329日更新

问题门6回:研究内核源码的切入点在哪里,或者说从哪个模块开始研究对新手比较适合,是否有一些必读的基础型的模块源代码?(Roger_jin提出)

fudan_abc的回答:

没有那些所谓的必读的基础性源代码,呵呵,只要按照韩峰同志的那种态度去分析选定部分的源代码,那些所谓基础性的东东都会在分析过程中明白理解的。有上下文的帮助,反而会更容易理解那些之前理解不了的“基础知识”。

至于切入点,没有什么特别的推荐,主要是依赖自己的兴趣或者开发需要了。

2010年3月24日更新

“问题门”第5回:学习Linux内核,应该从Linux哪个版本代码开始阅读更好呢?

fudan_abc的回答:

个人建议从新的内核开始,固然新内核的代码非常庞大,但并没有说非要求大求全,追求每个部分都要理解。

学内核忌讳求大而全,如果对哪部分比较感兴趣,研究相关的源码和change就行了,当然仁者见仁智者见智,自己如果觉得从低版本开始更好更适合,那采用这种方式也未尝不可,毕竟各人的路还是各自走的。

2010年3月23日更新

“问题门”第3回:通常,语言及其库的学习分为几个层次,1.熟练使用,2.阅读源码,了解实现原理,3.对源码进行扩展。那么linux kernel怎么划分层次,每个层次如何达到?(hust_tulip提出)

fudan_abc的回答:

问题中的三个层次对应到linux内核的学习上:“熟练使用”就是要能够熟练的使用linux系统;“阅读源码”就是指“学习内核就是学习内核源代码”,必须勇敢的去学习内核源码;“对源码进行扩展”可以对应于融入内核社区,参与内核的开发。

这也正好在一定程度上锲合了本书前言里对内核学习划分的几个层次:全面了解抓基本,兴趣导向深钻研;融入社区做贡献,坚持坚持再坚持。

——详见修炼之道 之 前言

“问题门”第4回:每个层次的学习都有什么对应的参考资料以及网络资源?(hust_tulip提出)

fudan_abc的回答:

首先是“全面了解抓基本”,这个层次,最好的书自然就是lkd和ulk了,这两本书,一本提纲挈领,一本全面深入,都能很好的帮助全面的理解内核的整体机制。新人的话,一本lkd就足亦了。

第二个层次“兴趣导向深钻研”,这个层次就是要以内核源码为中心,选择内核中一个自己感兴趣的部分,以韩峰同志对待日记的态度,严谨而细致的仔细分析它的代码,不懂的地方就通过社区、邮件列表或者直接发Email给maintainer请教等途径弄懂,切勿得过且过。至于这个层次的参考书么,网络子系统的有《深入理解LINUX网络内幕》,内存管理的有《深入理解Linux虚拟内存管理》,推荐看英文版,呵呵,usb的可以看我们的《Linux那些事儿》,其它子系统的还没注意到有什么专门讲解的,不过内核源码本身就是最好的参考资料了。

至于第三个层次“融入社区做贡献”,就是要努力融入到内核的开发社区,经过前两个层次的修炼,此时你已经不会再是社区中潜水小白的角色,而是会针对某个问题发表自己的见解。可以尝试参与到内核的开发中去。相关资源有很多,详细可以参考修炼之道精华篇的(9)内核学习资源

最后一层就是坚持了,不管遇到什么挫折都不放弃,就像咱们的袁教授不管遭受到什么样的辱骂都要坚持不断的发疯一样,有这样的精神,何愁在linux内核的学习道路上修不成大道那?

2010年3月22日更新

“问题门”第1回:我是一个初学者,两眼一抹黑,我该如何学习内核?

fudan_abc的回答:

这个问题每个初学者都无法回避,它非常之大,完全可以做为整个“问题门”的框架而存在,其他的各种问题都不过是在这个框架上装饰和完善。

同时这个问题并没有一个标准的答案,只有一些学习的脉络可以遵循,祝早日“入门”。

第一步:先会使用它。连Linux是什么、基本操作都不会就去研究内核,纯属扯淡,“门”都没有。

第二步:看懂内核源码需要一些操作系统、C语言等的基础。

第三步:找本合适的内核参考书,让它帮助你对内核有个整体的理解和认识,

第四步:要能够动手配置编译内核,还要基本看得懂内核中的Kconfig和Makefile文件。

最后,记住:“学习内核,就是学习内核的源代码,任何内核有关的书籍都是基于内核,而又不高于内核的。内核源码本身就是最好的参考资料,其他任何经典或非经典的书最多只是起到个辅助作用,不能也不应该取代内核代码在我们学习过程中的主导地位。”

因此你要做得是选择内核的一个部分或子系统,以韩峰同志对待日记的态度,严谨而细致得理解每一段代码的实现,多问多想多记。切勿抱着走马观花,得过且过的态度。

“问题门”第2回:学习内核需要什么基础知识?

albcamus的回答:

(1)需要掌握操作系统理论的最初级的知识。

不需要通读并理解《操作系统概念》《现代操作系统》等巨著,但总要知道分时(time-shared)和实时(real-time)的区别是什么,进程是个什么东西,CPU和系统总线、内存的关系(很粗略即可),等等。

(2)熟练使用C语言。

不需要已经很精通C语言,只要能熟练编写C程序,能看懂链表、散列表等数据结构的C实现,用过gcc编译器,就可以了。当然,如果已经精通C语言显然是大占便宜的。

(3)了解CPU的相关知识,

Linux内核学习经验

1. 内核学习的心理误区

心理上的问题主要有两个,一个是盲目,就是在能够熟练使用Linux之前,对Linux为何物还说不出个道道来,就迫不及待的盲目的去研究内核的源代码。重述Linus的那句话:要先会使用它。

第二个就是恐惧。人类进化这么多年,面对复杂的物体和事情还是总会有天生的惧怕感,体现在内核学习上面就是:那么庞大复杂的内核代码,让人面对起来该情何以堪啊!

有了这种恐惧无力感存在,心理上就会去排斥面对接触内核源码,宁愿去抱着情景分析,搜集各种各样五花八门的内核书籍放在那里屯着,看了又忘,忘了又看,也不大情愿去认真细致得浏览源码。
          ——详见修炼之道精华篇(9)内核学习的心理问题

2. 学习内核就是学习内核的源代码

学习内核,就是学习内核的源代码,任何内核有关的书籍都是基于内核,而又不高于内核的。内核源码本身就是最好的参考资料,其他任何经典或非经典的书最多只是起到个辅助作用,不能也不应该取代内核代码在我们学习过程中的主导地位。

3. 要抱着严谨细致的态度分析内核源码

既然要学习内核源码,就要经常对内核代码进行分析,而内核代码千千万,还前仆后继的不断往里加,这就让大部分人都有种雾里看花花不见的无助感。不过不要怕,孔老夫子早就留给我们了应对之策:敏于事而慎于言,就有道而正焉,可谓好学也已。这就是说,做事要踏实才是好学生好同志,要遵循严谨的态度,去理解每一段代码的实现,多问多想多记。如果抱着走马观花,得过且过的态度,结果极有可能就是一边看一边丢,没有多大的收获。

只要你使用这样的态度开始分析内核,那么无论你选择内核的哪个部分作为切入点,比如USB,比如进程管理,在花费相对不算很多的时间之后,你就会发现你对内核的理解会上升到另外一个高度,一个抱着情景分析,抱着0.1内核完全注释,抱着各种各样的内核书籍翻来覆去的看很多遍又忘很多遍都无法达到的高度。
           ——详见修炼之道精华篇(6)精华篇(7) 分析内核源码如何入手?

4. 通过Kconfig与Makefile定位目标代码

毫不夸张地说,Kconfig和Makefile是我们浏览内核代码时最为依仗的两个文件。基本上,Linux内核中每一个目录下边都会有一个Kconfig文件和一个Makefile文件。
对于一个希望能够在Linux内核的汪洋代码里看到一丝曙光的人来说,将它们放在怎么重要的地位都不过分。

Kconfig和Makefile就是Linux
Kernel迷宫里的地图。地图引导我们去认识一个城市,而Kconfig和Makefile则可以让我们了解一个Kernel目录下面的结构。我们每次浏览kernel寻找属于自己的那一段代码时,都应该首先看看目录下的这两个文件。就像利用地图寻找目的地一样,我们需要利用Kconfig和Makefile来寻找所要研究的目标代码。
          ——详见修炼之道精华篇(5)Kernel地图:Kconfig与Makefile

原文地址:https://www.cnblogs.com/alantu2018/p/8448802.html

时间: 2024-11-05 18:55:04

Linux内核“问题门” - 学习问题、经验集锦的相关文章

Linux内核调试的方式以及工具集锦

CSDN GitHub Linux内核调试的方式以及工具集锦 LDD-LinuxDeviceDrivers/study/debug 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可, 转载请注明出处, 谢谢合作 因本人技术水平和知识面有限, 内容如有纰漏或者需要修正的地方, 欢迎大家指正, 也欢迎大家提供一些其他好的调试工具以供收录, 鄙人在此谢谢啦 "调试难度本来就是写代码的两倍. 因此, 如果你写代码的时候聪明用尽, 根据定义, 你就没有能耐去调试它了.&qu

Linux内核分析第一次学习报告

Linux内核分析第一次学习报告 学生 黎静 学习内容 1.存储程序计算机工作模型 冯诺依曼体系结构:核心思想为存储程序计算机. CPU抽象为for循环,总是执行下一条指令,内存保存指令和数据,CPU来解释和执行这些指令. API:应用程序编程接口(程序员与计算机的接口界面) ABI:二进制接口,指令编码(程序员与CPU的接口界面) 2.X86汇编 1.寄存器 (1)通用寄存器 (2)段寄存器: (3)标志寄存器 2.计算机的汇编指令 (1)movl指令: 寄存器寻址,寄存器模式,以%开头的寄存

linux内核启动过程学习总结

下面是学习linux内核启动过程的记录 平台是:powerpc mpc8548 + linux2.6.23 内核 通用寄存器的作用r0 :在函数开始时使用r1 :存放堆栈指针,相当于ia32架构中的esp寄存器r2 :存放当前进程的描述符的地址r3 :存放第一个参数和返回地址r4-r10 :存放函数的参数r11 :用在指针的调用和当前一些语言的环境指针r12 :用于存放异常处理r13 :保留做为系统线程IDr14-r31 :作为本地变量,具有非易失性 Linux启动过程描述 第一步:使用Boot

《Linux内核分析》学习总结与学习心得

一.目录列表 第一周:计算机是如何工作的? http://www.cnblogs.com/dvew/p/5224866.html 第二周:操作系统是如何工作的? http://www.cnblogs.com/dvew/p/5245866.html 第三周:构造一个简单的Linux系统MenOS http://www.cnblogs.com/dvew/p/5270915.html 第四.五周:系统调用的三层皮 http://www.cnblogs.com/dvew/p/5285685.html h

Linux内核(17) - 高效学习Linux驱动开发

这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到写上去的每段话能够让读者产生什么疑惑,然后也都会紧接着尽量的去进行解释清楚,中间的很多概念也有反复纠结过怎么解释能够更容易的理解,力求即使对于初学者也可以有很少阻碍的一气读完.同时我也把书中一部分自己的感悟抽出来整理了精华版,share出来.当然水平有限,错漏之处有发现而修订时遗漏的,也有尚没有发现的.这本书

Linux内核源码学习之 数据结构

本篇记录在学习Linux内核源码过程中对一些知道但不熟悉不会用的数据结构进行记录. union 是在学习进程复制函数do_fork中遇到的: <sched.h> union thread_union { struct thread_info thread_info; unsigned long stack[THREAD_SIZE/sizeof(long)]; }; struct  thread_info和stack被声明为union 共享空间 "联合"是一种特殊的类,也是一

linux内核基础层的学习(1)

一:内核基础层数据结构 1:双向链表list a):链表的定义 struct list_head{ struct list_head *next,*pre; } b):container对象和list_entry #define container_of(ptr,type,member){ \ const typeof(((type *)0->member) *_mptr = (ptr); (type*)((char*)_mptr-offset(type,member));}) #define

Linux内核(16) - 高效学习Linux内核

世界悲结束了,章鱼哥也退役了,连非诚勿扰中的拜金女也突然的少了很多.这本<Linux内核修炼之道>在卓越.当当.china-pub上也已经开卖了,虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到写上去的每段话能够让读者产生什么疑惑,然后也都会紧接着尽量的去进行解释清楚,中间的很多概念也有反复纠结过怎么解释能够更容易的理解,力求即使对于初学者也可以有很少阻碍的一气读完.同时我也把书中一部分自己的感悟抽出来整理了精华版,share出来.当然水平有限,

Linux内核d_path函数应用的经验总结

问题背景 一个内核模块中,需要通过d_path接口获取文件的路径,然后与目标文件白名单做匹配. 在生产环境中,获取的文件是存在的,但是与文件白名单中的文件总是匹配失败. 问题定位: 通过打印d_path返回的字符串,发现获得的路径后面多了一个" (deleted)"字符串,在做完全匹配时不通过. 看了d_path函数说明:如果entry被删除了,会添加" (deleted)"字符串. * Convert a dentry into an ASCII path nam