一、设备号
主设备号和次设备号是放在同一个32位的整型变量里,变量类型重定义为dev_t。
二、设备号的注册
静态注册:
找出一个未使用的设备号,用函数来注册。
会面临可移植性的问题。
动态注册:
让系统分配一个未使用的设备号。
可以使用alloc_chrdev_region函数动态申请。
int alloc_chrdev_region(dev_t* ,unsigned ,unsigned ,const char* );
参数1:保存动态分配的设备号的变量地址
参数2:次设备号的起始编号
参数3:次设备的数量
参数4:注册的时候提供的名字
三、设备文件的创建
需要主次设备号。设备文件要和驱动相一致,因而设备号要一致。实际上就是通过设备号找到特定的驱动的。
mknod /dev/mydev c 主设备号 次设备号
2、动态创建设备文件
模块插入系统的时候让系统自动创建设备文件。
系统创建设备文件的过程:
有一个守护进程udev,他会扫描/sys/class下的文件夹,一旦有新的文件加入,就会根据文件信息,自动在/dev下创建相应设备文件。
class的创建:
struct class *class_create(struct modules *owner,const char *name)
参数1:class的属主,通常使用THIS_MODULE
class的销毁:
void class_destroy(struct class *cls);
device的创建:
struct device *device_create(struct class *cls, struct device *parent,
dev_t devt, void *drvdata,
const char *fmt, ...)
第一个参数表示该设备属于哪个class,
第二个是父亲,通常NULL。
第三个是设备号,第四个是私有数据,通常也是NULL。
第五个是名字。
device的销毁:
void device_destroy(struct class *cls, dev_t devt);
函数实例:
mydev.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h> //设备号注册相关
#include <linux/device.h> //class和device相关
MODULE_LICENSE("GPL");
dev_t devno;//设备号
struct class *cls; //设备类
static int __init myinit(void)
{//在模块初始化时,动态申请前设备号
alloc_chrdev_region(&devno,10,1,"mydev");
cls=class_create(THIS_MODULE,"myclass");//创建类
device_create(cls,NULL,devno,NULL,"mynewdev");//在类下面创建设备
printk("major is %d, minor is %d\n",MAJOR(devno),MINOR(devno));
return 0;
}
module_init(myinit);
static void __exit myexit(void)
{//模块清理的时候,反注册设备号
device_destroy(cls,devno);//销毁设备
class_destroy(cls);//销毁类
unregister_chrdev_region(devno,1);//反注册设备号
}
module_exit(myexit);
Makefile:
KERN=/usr/src/kernels/`uname -r`
SRC=`pwd`
obj-m+=mydev.o
all:
make -C $(KERN) M=$(SRC) modules
clean:
make -C $(KERN) M=$(SRC) clean