8 静态申请字符类设备号 这里开始介绍的是纯粹的字符设备,前面学习的是杂项设备,主设备号已经固定为10。字符设备分为静态申请和动态申请,静态申请就是主设备号是程序员手动分配了,动态申请是系统给分配,本实验先介绍静态申请的方法。 Linux 的设备主要分为三大类,字符设备、块设备、网络设备。前面写的驱动是杂项设备,它和字符设备唯一的区别就是主设备号已经搞定了,不需要像字符设备那样去手动申请。 8.1 申请字符类设备的函数 如下图所示,在头文价“include/linux/fs.h”中,可以找到三个注册字符设备的函数。这三个分别是函数register_chrdev_region,函数alloc_chrdev_region,函数register_chrdev()。
函数register_chrdev_region()是提前知道设备的主次设备号,再去申请设备号。函数alloc_chrdev_region() 是动态分配主次设备号。函数register_chrdev()。是老版本的设备号注册方式,只分配主设备号。从设备号在mknod的时候指定。这个函数现在虽然仍然可以支持,但是已经不再使用了。 8.2 静态申请字符设备号 静态申请函数register_chrdev_region(dev_t, unsigned, const char *)。在头文件“include/linux/cdev.h”中的cdev 中有专门一个参数dev_t dev,如下图所示。
cdev 类型是是字符设备描述的结构,其中的设备号必须用“dev_t”类型来描述,高12 位为主设备号,低20 位为次设备号。把dev 理解为二进制数,就很容易理解了,dev_t 是一个32 位类型的数,前12 位表示主设备,后20 位表示次设备号。如下图所示,在头文件“include/linux/kdev_t.h”中,有一些专门用来处理dev_t 数据类型的宏定义。
如上图所以,三个函数比较容易理解。MAJOR(dev),就是对dev 操作,提取高12 位主设备号;MINOR(dev) ,就是对dev 操作,提取低20 位数次设备号MKDEV(ma,mi) ,就是对主设备号和低设备号操作,合并为dev 类型。 8.3 源代码 如下图所示,先调用头文件,然后将主设备号和设备号通过模块参数传入,定义此设备号数。
接着将入口函数和出口函数名称修改一下,“hello_init”和“hello_exit”改为“scdev_init”和“scdev_exit”。
如下图所示,在入口和出口函数中调用函数register_chrdev_region 和函数unregister_chrdev_region。
如上图所示,先将主设备号和次设备号默认为0,然后做一个简单的判断。如果没有参数传入,默认为零,就会提示注册失败;如果参数传入的话,和已有的主次设备号有重复,也会失败。
|