Linux内核设备驱动之字符设备驱动笔记整理

2019-01-16 20:44:33王振洲
/******************** * 字符设备驱动 ********************/

(1)字符设备驱动介绍

字符设备是指那些按字节流访问的设备,针对字符设备的驱动称为字符设备驱动。

此类驱动适合于大多数简单的硬件设备。比如并口打印机,我们通过在/dev下建立一个设备文件(如/dev/printer)来访问它。

用户应用程序用标准的open函数打开dev/printer,然后用write向文件中写入数据,用read从里面读数据。

调用流程:

write(): 用户空间 --> sys_write(): VFS --> f_op->write: 特定设备的写方法

所谓驱动,就是提供最后的write函数,通过访问打印机硬件的寄存器直接和打印机对话

(2)主设备号和次设备号

a.设备编号介绍

对字符设备的访问是通过文件系统内的设备文件进行的。这些文件位于/dev。用"ls -l"查看。

设备通过设备号来标识。设备号分两部分,主设备号和次设备号。

通常,主设备号标示设备对应的驱动程序,linux允许多个驱动共用一个主设备号;

而次设备号用于确定设备文件所指的设备。

在内核中,用dev_t类型<linux/types.h>保存设备编号。

2.4内核中采用16位设备号(8位主,8位从),而2.6采用32位,12位主,20位从。

在驱动中访问设备号应该用<linux/kdev_t.h>中定义的宏。

获取设备号:

MAJOR(dev_t dev) MINOR(dev_t dev) MKDEV(int major, int minor)

b.分配和释放设备编号

在建立一个字符设备前,驱动需要先获得设备编号。

分配:

#include <linux/fs.h> int register_chrdev_region(dev_t first, unsigned int count, char *name); //first:要分配的设备编号范围的起始值(次设备号常设为0) //count: 所请求的连续编号范围 //name: 和编号关联的设备名称(见/proc/devices)

也可以要求内核动态分配:

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); //firstminor: 通常为0 //*dev: 存放内核返回的设备号

释放:

void unregister_chrdev_region(dev_t first, unsigned int count); //在模块的清除函数中调用

在Documentation/devices.txt中可以找到内核已经分配的设备号。

c.建立设备文件

当设备驱动模块向系统申请了主设备号和次设备号,并且已经通过insmod加载到内核中后,我们就可以通过在/dev下创建设备文件来访问这个设备了。

字符设备的创建:$>mknod /dev/mychar c major minor

我们在驱动中常常采用动态分配主次设备号的方法,这样不会和系统中已有的设备号冲突。

动态分配时,/dev下的设备文件也需要通过分析/proc/devices动态建立。