char_device_struct中含有cdev *cdev,所以也是一个数组;该数组通过次设备号找到对应的file_operations;
chrdevs也是一个数组,以主设备号找到char_device_struct;
主次设备号以结合得到确切的设备。
1、经由cdev的注册
cdev结构体定义
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
相关注册函数:
void cdev_init(struct cdev * cdev, const struct file_operations * fops)
将fops填充到cdev中
int cdev_add(struct cdev * p, dev_t dev, unsigned count)
将cdev这个结构体添加到内核中(穿在内核里)
void cdev_del(struct cdev *)
注册流程
1、自定义主次设备号major,并将设备号注册;等于在chrdevs[]中占据位置;创建char_device_struct成功。
devno = MKDEV(major,minor);
result = register_chrdev_region(devno, 1, "hello_test");
2、注册file_operation,完成对cdev的初始化,并将其填充进入内核;
static struct file_operations hello_ops =
{
.open = hello_open,
.......
};
cdev_init(&cdev,&hello_ops);
int error = cdev_add(&cdev,devno,1);
if(error < 1)
{
printk("cdev add fail \n");
/* 谁申请谁释放,无论是出错还是卸载都需要释放掉 */
unregister_chrdev_region(devno, 1);
return error;
}
3、依次销毁cdev以及设备号,先申请后释放,后申请先释放。
cdev_del(&cdev);
unregister_chrdev_region(devno,1);