面对不断升级的内核如何学习linux设备驱动
面对不断升级的linux内核、GNU开发工具、linux环境下的各种图形库,很多linux应用程序开发人员和linux设备驱动开发人员即兴奋,又烦躁。兴奋的是新的软件软件、工具给我提供了更强大的功能,烦躁的是适应新软件的特性、搭建新环境是一项非常繁琐的事情。本文想从以下3个方面探讨一下“面对不断升级的内核,如何学习linux设备驱动”。
内核发展的现状及其对技术人员的影响
Linux目前主要维护2.4和2.6两个内核版本。在http://www.kernel.org/ 网站上已经可 以下载到最新的2.6内核linux-2.6.31,及最新的2.4内核linux-2.4.37。稳定版本号基本上是1~3月更新一次,如:2.6.22至2.6.23。升级版本号每1~2周更新一次,如:2.6.23.1至2.6.23.2。
由于高版本内核并不完全兼容低版本内核,所以内核升级对从事linux开发的技术人员造成了一定的影响,特别对于linux入门人员。
内核的升级对应从事linux应用程序开发的人员来说影响较小,因为系统调用基本保持兼容。而影响比较大的是驱动开发人员。每次内核的更新都可以导致很多内核函数使用上的变化。其中有内核本身提供的函数,也有硬件平台代码提供的函数,后者变化的更加频繁。这一点让初学内核驱动的人很迷茫,因为当他们按照手里的经典著作,如:Alessandro的《linux设备驱动程序》,编写驱动时,发现并不能够成功的在你的linux平台上编译通过、或不能正常执行。你的朋友会告诉你,你用的内核和书里的不一致。那该怎么办呢?
我想从两个方面去解释这个问题,一方面是如何写好linux设备驱动,另一方面是如何应对不断升级的内核。
如何写好Linux设备驱动
Linux设备驱动是linux内核的一部分,是用来封装硬件细节,为上层提供标准接口的一种方法。为了能够编写出质量比较高的驱动,要求工程师必须具备以下几个方面的知识:
熟悉处理器的性能
如:处理器的体系结构、汇编语言、工作模式、异常处理等此项对于初学者来说,重要程度:***。也就是说还不熟悉驱动编写方法的情况下,可
以先不把重心放在这一项上,因为可能因为它的枯燥、抽象而影响到你对设备驱动的兴趣。
随着你不断的熟悉驱动的编写,你会很自然的意识到此项的重要性。
掌握驱动目标的硬件工作原理及通讯协议
如:串口控制器、显卡控制器、硬件编解码、存储卡控制器、I2C通讯、SPI通讯、USB通讯、SDIO通讯、I2S通讯、PCI通讯等
此项的重要程度应该不用多说了,编写设备驱动的前提就是知道设备的操作方法。但不是说要把所有设备的操作方法都熟悉了以后才可以驱动,你只需要了解你要驱动的硬件就可以了。所有这一项对于初学者来说重要程度都是:*****。
掌握硬件的控制方法
如:中断、轮询、DMA 通常一个硬件控制器会有多种控制方法,你需要根据系统性能的需要合理的选择操作方法。
此项对于初学者来说:重要程度:****。初学阶段以实现功能为目的。掌握的顺序应该是,轮询->中断->DMA。随着学习的深入,需要综合考虑系统的性能需求,采取合适的方法。
良好的GNU C语言编程基础
如:C语言的指针、结构体、内存操作、链表、队列、栈、C和汇编混合编程等。
这些编程语法是编写设备驱动的基础。
此项无论对于初学者还是熟手重要程度:*****。
良好的linux操作系统概念
如:多进程、多线程、进程调度、进程抢占、进程上下文、虚拟内存、原子操作、阻塞、睡眠、同步等概念及它们之间的关系。
这些概念及方法在设备驱动的使用是linux设备驱动区别单片机编程的最大特点。只有理解了它们才会编写出高质量的驱动。
此项对于初学者来说:重要程度:***。开始可以以实现功能为目的,逐步完善自己的驱动。
掌握linux内核中设备驱动的编写接口
如:字符设备的cdev、块设备的gendisk、网络设备的net_device,以及基于这些基本接口的framebuffer设备的fb_info、mtd设备的mtd_info、tty设备的tty_driver、usb设备的usb_driver、mmc设备的mmc_host等
Linux内核为设备驱动编写者留下了标准的接口。驱动编写者无需精通内核的各个部分,只需要明确内核留给我们的接口,并实现此接口就可以了。内核流出的接口采用的是面向对象的思路,即把目标设备看成一个对象,通常利用一个结构体来描述这个对象。驱动工程师的任务就是实现这个对象。这个结构体中会包含设备的属性(用变量表示)和操作方法(用函数指针表示)。如:字符设备的cdev
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops; //操作方法结合,其它项都是属性
struct list_head list;
dev_t dev;
unsigned int count;
};
- REDIce-Linux--灵活的实时Linux内核(11-12)
- linux文件系统基础(02-09)
- Linux标准趋向统一(11-12)
- linux基础技术(02-09)
- LINUX的目录树(02-09)
- 在Windows下启动Linux(02-09)