本人是一名 android display方面的工程师,结合实际工作经验聊聊(观点未必正确)
1. 准备工作:选择什么样的版本,使用什么样的工具,这个需要考虑好。
如果是要参考书的话,kernel版本一般都应该选择和书里面同步的版本,不要去选择最新的版本。因为最新的版本,各种改动比较多,反而对不上书了。
工具问题,你可以选择windows下的source insight,也可以选择linux下vim+ctags;
2. 第一遍浏览,我建议是先把kernel里面的 start_kernel() 函数里面的东西看清楚(不一定看明白),看看这个过程中,出现了什么玩意,有哪些分支,并将分支初略的画出一张图来(当然,我自己并没做到这一点,有点讽刺了)。
这里面最重要的几个地方,我个人认为,应该搞明白module机制,它是怎么通过编译链接脚本放在特定的区域,然后系统起来后,又是如何去(按照什么规则)去加载这些模块;
应该搞明白sysfs系统,这个对于驱动和用户空间的连接,有非常大的作用;
系统调用的open()应该走一遭,看看用户空间到kernel之间参数是如何传递,又是怎么通过vfs系统,把open的动作最终落实到某一个驱动的open()上去的;
对kernel启动过程中,内存的分配算法,是怎么从伙伴算法切换到最终的算法上,也应该略有耳闻;对fork()函数的过程有所明白。
对kernel中基本的数据结构实现过程、锁机制实现过程要有概念:
这一部分,总结起来,应该看的路线是:
start_kernel()
module_init() 宏实现 // 看这个的时候,强烈建议,把makefile真正的意图弄明白
open() 系统调用
fork() 系统调用
sysfs 框架实现
双链表是如何实现的;
锁最终是依靠什么来保证的?(其实还是硬件来保证的)
对于数据结构和锁这部分,就按照《Linux内核设计与实现》里面的东西挨个挨个看。有兴趣,自己也可以实现一个双链表公共API,随便哪个项目,一旦用上,直接抛进去,也未尝不可。
第一遍浏览,窃以为,上面这几部分看明白后,kernel的代码对你依然很难,但已经不再有神秘的面纱。
后续,你想研究某个模块,直接快速定位到那边去就行。
3. 在完全用眼睛看完上面这部分内容后,kernel的路或许找到了,但是,万里长征的第一步,并没有迈出。这个时候,动手是很重要的了。
网上有各种方法,比如说,去kernel maillist里面订阅bug,然后自己试着解bug,此方法可取,而且是非常好。这里会遇到一个问题是,我们该怎么调试?
有人是架各种虚拟机或者多台物理机一起开干,这个可以有。(但是本人动手能力确实有限,这个没干成,本人是后面借助了公司的开发板)
如果你也像我一样,动手能力不足,如果你恰巧是手机或者类似手机开发公司的,你可以直接使用公司的开发机,通过串口log,将printk()的级别设置为3,把你需要的信息打印出来;
如果你是学生或者爱好者,可以花500左右人民币,去淘宝上买一个开发板,也是带串口的,所有的debug信息都是通过串口打印出来,保存到一个Log文件中,然后分析;
至于买什么样的板子,你可以随便选择,经典的s3c2440也行,高端点的树莓派,或者全志什么的,都可以。(不推荐全志,他们添加和修改硬件比较多,驱动也许不好搞)
4. 选择你喜欢的模块,进行深入研究,通过log打印,反复推敲,这个时候,bug是最好的导师。多关注kernel/Documents/ 目录下的文档。
你需要注意的是,一定要把该模块无关的东西砍掉,否则,生命是有限的,而代码是无限的。
最后一句话是,在用眼睛看完后,思考过后,还得动手,然后再思考。否则,只读的话,仅能扫盲。