字符驱动:cdev一般有两种初始化方式:静态和动态
GFP_KERNEL:在linux/gfp.h中定义的一个宏,是分配内核空间的内存时的一个标志位。
静态1: struct cdev my_cdev;
cdev_init(&my_cdev,&fops);
my_cdev.owner=THIS_MODULE;
cdev_add(my_cdev, my_dev, 1 );
静态2: struct user_dev{
int uerdata;
struct cdev cdev;
};
struct user_dev *my_dev;
my_dev=kmalloc(sizeof(struct user_dev),GFP_KERNEL);
my_dev->userdata=0;
cdev_init(&my_dev->cdev,&fops);
my_dev->cdev.owner=THIS_MODULE;
cdev_add(&my_dev->cdev,my_dev,1);
动态: struct cdev* my_dev;
my_dev=cdev_alloc();
my_cdev->ops=&fops; // 注意这些,别忘添加
my_cdev->owner=THIS_MODULE;
//cdev_init(my_cdev,&fops);//可以去掉
cdev_add(my_cdev, my_dev, 1 );
struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p) {
INIT_LIST_HEAD(&p->list);
kobject_init(&p->kobj, &ktype_cdev_dynamic);
}
return p;
}
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
}
两个函数完成都功能基本一致,只是 cdev_init() 还多赋了一个 cdev->ops 的值。
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
p->dev = dev;
p->count = count;
return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
}
void cdev_del(struct cdev *p)
{
cdev_unmap(p->dev, p->count);
kobject_put(&p->kobj);
}
GFP_KERNEL:在linux/gfp.h中定义的一个宏,是分配内核空间的内存时的一个标志位。
静态1: struct cdev my_cdev;
cdev_init(&my_cdev,&fops);
my_cdev.owner=THIS_MODULE;
cdev_add(my_cdev, my_dev, 1 );
静态2: struct user_dev{
int uerdata;
struct cdev cdev;
};
struct user_dev *my_dev;
my_dev=kmalloc(sizeof(struct user_dev),GFP_KERNEL);
my_dev->userdata=0;
cdev_init(&my_dev->cdev,&fops);
my_dev->cdev.owner=THIS_MODULE;
cdev_add(&my_dev->cdev,my_dev,1);
动态: struct cdev* my_dev;
my_dev=cdev_alloc();
my_cdev->ops=&fops; // 注意这些,别忘添加
my_cdev->owner=THIS_MODULE;
//cdev_init(my_cdev,&fops);//可以去掉
cdev_add(my_cdev, my_dev, 1 );
struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p) {
INIT_LIST_HEAD(&p->list);
kobject_init(&p->kobj, &ktype_cdev_dynamic);
}
return p;
}
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
}
两个函数完成都功能基本一致,只是 cdev_init() 还多赋了一个 cdev->ops 的值。
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
p->dev = dev;
p->count = count;
return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
}
void cdev_del(struct cdev *p)
{
cdev_unmap(p->dev, p->count);
kobject_put(&p->kobj);
}