要掌握读懂linux内核不是一件容易的事情,除了要掌握操作系统原理和熟悉一些硬件、编译原理和各种框架、概念以外,还要懂得linux kernel源码在编码方式上使用的一些技巧。
我们刚开始为什么读不懂内核源码呢,一部分原因就是它的编码认知高度在我们普通人之上,至少在我之上。我总结了部分linux内核代码使用的一些技巧,并取了名字,其它没想到名字的就没列出来。
我发现第7条,"兄弟两地发展,过年老家团圆“,这样的技巧很多人不太熟悉,也可能一时想不起来,我重点说这一条吧。
比如我最近看framebuffer方面的源码,看到一个DC设备probe函数要调用到register_framebuffer,这个函数里面突然调用device_create()这样的函数,前面没看到有注册fops,直觉告诉我,这是一个字符设备,而且它没有fops就玩不转。而且我们这边是framebuffer的设备,已经实现了fb_ops。
这系列函数肯定要在这个字符设备的节点上通过read,write,ioctl等等这样的函数调用到,因为内核就是这样玩的。然后我用FB_MAJOR去搜索
看到了吧,原来framebuffer框架在公用代码里面早早就调用了register_chrdev. 我们查看一下fb_fops.
重点看fb_open这个函数,因为字符设备一般会在打开的时候做一些神操作,比如会建立纽带。
可以看到iminor()利用inode上面的i_rdev设备号成员找到fb_index,继而找到framebuffer设备。
这样一来framebuffer的公共代码就跟自己实现的fb_ops完美结合在一起了。
这样是一个非常好的编码方式,其实内核到处都是这样玩的,内核只管实现自己的通用代码,然后我们程序员实现自己的fb_ops,在设备open的时候结合,终于回家大团圆。