Linux 设备驱动概述
1.内核和驱动模块
操作系统是通过各种驱动程序来甲鱼硬件设备,它为用户屏蔽了各种各样的设备,驱动硬件是操作系统最基本的功能,并且提供统一的操作方式。正如我们查看屏幕上的文档时,不用去管到底使用nVIDIA芯片,还是ATI芯片的显示卡,只需要知道输入命令后,需要的文字就显示在屏幕上。硬件驱动程序是操作系统最基本的组成部分,在Linux内核源程序中也占有较高的比例。
Linux内核中采用可加载的模块化设计(LKMs, Loadable Kernel Modules), 一般情况下编译的Linux内核是支持可插入式模块的,也就是将最基本的核心代码编译在内核中,起塔的代码可以选择是在内核中,或者编译为内核的模块文件。
如果需要某种功能,比如需要访问一个NTFS分区,就加载相应的NTFS模块。这种设计可以使内核文件不至于太大,但是又可以支持很多的功能,必要时动态地加载。这是一种跟微内核设计不太一样,但却是切实可行的讷河设计方案。我们常见的驱动程序就是作为内核模块动态加载的,比如声卡驱动和网卡驱动等,而Linux最基础的驱动,如CPU、PCI总线、TCP/IP协议、APM(高级电源管理)、VFS等驱动程序则编译在内核文件中。有时, 也把内核模块叫做驱动程序,只不过驱动的内容不一定是硬件罢了,比如ext3文件系统的驱动。这一点很重要,因此,加载驱动时就是加载内核模块。下面来看一下有关模块的命令,在加载驱动程序要用到它们:lsmod、modprob、insmod、rmmod和modinfo。
lsmod
功能:列出当前系统中加载的模块。
显示结果重点说明:如果后面标志位unused,则表示该模块当前没有使用。如果后面有autoclean,则该模块可以被rmmod -a命令自动清理。rmmod -a命令会将目前有autoclean的模块卸载,如果这时候某个模块未被使用,则将该模块标记为autoclean。如果再行尾的[ ]括号内有模块名称,则括号内的模块就依赖于该模块。如:
cdrom 34144 0 [sr_mod ide-cd] 其中,ide-cd及sr_mod模块就依赖于cdrom模块。
系统的模块文件保存在/lib/modules/2.4.XXX/kernel目录中,根据分类分别在fs、net等子目录中,他们的互相依存关系则保存在/lib/modules/2.4.XXX/modules.dep文件中。
需要注意的是,该文件不仅写入了模块的依存关系,同时讷河查找模块也是在这个文件中,使用modprobe命令,可以智能插入模块,它可以根据模块间依存关系,以及/etc/modules.conf文件中的内容智能插入模块。比如希望加载ide的光驱驱动,则可用以下命令:
modprobe ide-cd 此时会发现,cdrom模块也会自动插入。
insmod也是插入模块的命令,但是它不会自动解决依存关系,所以一般加载讷河模块时候使用的命令是modprobe。
rmmod可以删除模块,但是它只可以删除没有使用的模块。
modinfo用来查询模块信息,如modinfo -d cdrom,在Red Hat Linux系统中,模块的相关命令在modutils的RPM包中。
2.设备文件
系统中的设备都用一个设备特殊文件代表,叫做设备文件,设备文件又分为Block(块)型设备文件、Character(字符)型设备文件和Socket(网络插件)型设备文件。
Block设备文件常常指定那些需要以块(如512字节)的方式写入的设备,比如IDE硬盘、SCSI硬盘和光驱等。
Character型设备文件常指定直接读写,没有缓冲区的设备,比如并口和虚拟控制台等。
Socket(网络插件)型设备文件指定的是网络设备访问的BSD socket 接口。
3.使用/proc目录中的文件见识驱动程序状态
Linux系统中proc文件系统是内核虚拟的文件系统,其中所有的文件都是内核中虚拟出来的,各种文件实际上是当前内核在内存中的参数。它就像是专门为访问内核而打开的一扇门,比如说访问/proc/cpuinfo文件,实际上就是访问目前CPU的参数,每一次系统启动时,系统都会通过/etc/fstab中设置的信息自动将proc文件系统加载到/proc目录下。
buzzer_driver.ko的驱动编译过程说明
在下列目录下执行"make"命令编译buzzer_driver.c
得到下列文件,其中有buzzer_driver.ko, 并装载此驱动模块
命令加载模块,通过“lsmod”命令,发现buzzerLiuQQ模块已被加载。在通过“cat /proc/devices”命令查看,发现多出了主设备号为249的“buzzerLiuQQ”字符设备驱动:
接下来,通过命令mknod /dev/BuzzerDriver c 249 0