其次,我们要注重对设备模型的理解。其实从 2.6 内核开始,随着设备模型的出现,驱动的开发就不再是个困难的问题,毫不夸张得说,理解了设备模型,再去看那些五花八门的驱动程序,你会发现自己站在了另一个高度,从而有了一种俯视的感觉,就像凤姐俯视知音和故事会,韩峰同志俯视女下属。不过貌似大部分驱动开发者都没意识到这个问题。
最后,是要养成使用协议的 spec 、设备的 datasheet 、内核参考代码去解决问题的习惯,而不是一碰到问题就到处寻找所谓的牛人去问怎么解决。
中间的那些内容和前面精华版的博文里差不多,就不贴了,…………
前面介绍了我个人感觉开发驱动需要注意的三个方面,现在说个实际的例子。这里咱们来看一下。
先说他个人的情况:有一定的 linux c 基础,熟悉 linux 内核 / 驱动的开发环境搭建和编译。现在想做个 i2c 芯片的 驱动,该驱动要跑在 x86 平台上。
手边的资料有:
1. 芯片手册 看了几次,基本了解 上边的 资源和 他的 i2c 地址
2. 找到 linux + arm 平台上的 对应的 .c 文件和 .h 文件。但是对应的 arm 平台的 kernel source 没有。
3. .c 文件里的 代码看过 一遍,从函数名 可以知道他的功能。
然后开始 操作 怎么移植这个 i2c 芯片到 x86 平台上。之后遇到了一些列的问题,比如 i2c 的地址信息等等,具体我就不叙述了。
然后他就去请教了一些人
请教某人 A : “ 其实 i2c 很简单,你填充那个 driver 结构体就 ok 了。 ” 我反问 “ 我对里边的 流程和调用不熟悉啊 “
A 回: ” 你把他们想象成一个黑盒就可以了 ” 我: “ 无法想象,我怎么想象?我想看看里边的代码到底是怎样的。 ”A:"....." 。 对 A 的请教结果,无法解决我的问题:我到底该怎么办?
再请教 B:
B:“ 其实 i2c 移植就是注册那几个函数 , 你想看内核代码实现,内核这么大你怎么可能搞清楚,我做了那么多移植,有时候连芯片手册都搞不清,直接 prink 吧代码给调出来的 ” 我: “ 。。。 ” 无法理解,无话可说。
其实这里边的 A 和 B 说的也没错,很多人写驱动大概就这么做的,但是这样子就是写成百上千个驱动也不能说就理解 linux 驱动了,面试时碰到的绝大部分人都属于这种情况,能回答自己做了什么,但一谈到一些相关的基本的问题就往往回答不上来。
我觉得首要的问题是缺乏好奇心,做技术的好奇心应该是原动力,特别对于搞 linux 内核和驱动的,好奇心有多强,你的水平就可能会增长到多高。
其次,对于做驱动的来说,对于 2.6 内核,重要的是去理解设备模型,很多人都本末倒置了,很多专门写驱动的书也不注重设备模型的理解,只去应付一种种类型的协议和设备的驱动,即使写个一万个也仅仅是对比较成熟的芯片熟了些。而且,不理解设备驱动,难道写驱动的时候不觉得很多东西很朦胧么?这也是我个人觉得很奇怪的一方面。
像我之前设备模型的文章里说的那样,理解了设备模型,对各种类型的驱动就有种俯视的感觉了。这个时候再你去看特定类型的协议和设备的实现,脉络就很清晰,比如你看 i2c 的实现。这个时候重要的就是 i2c 的协议,具体芯片的 datasheet ,加上看看内核里现有的 i2c 驱动作为参考,就是我所说的驱动开发的三件宝。
所以说如果希望做 2.6 的驱动话,关键还是要先去理解下设备模型,将这个比较抽象的概念在心里形象化,然后再去看具体的驱动比较好。