1:register_chrdev_region
int register_chrdev_region(dev_t from, unsigned count, const char *name) { struct char_device_struct *cd; dev_t to = from + count; dev_t n, next; for (n = from; n < to; n = next) { next = MKDEV(MAJOR(n)+1, 0); if (next > to) next = to; cd = __register_chrdev_region(MAJOR(n), MINOR(n), next - n, name); if (IS_ERR(cd)) goto fail; } return 0; fail: to = n; for (n = from; n < to; n = next) { next = MKDEV(MAJOR(n)+1, 0); kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n)); } return PTR_ERR(cd); }
register_chrdev_region函数和register_chrdev函数类似,也是用于字符设备驱动的注册,不同点在于register_chrdev函数在注册字符设备驱动的时候是一步完成的,而register_chrdev_region函数在注册字符设备驱动的时候是分两步完成的:
第一步:注册/分配主次设备号
第二步:注册字符设备驱动
此外有register_chrdev_region函数的源码可以发现,register_chrdev_region可以同时注册多个设备号
2:cdev结构体的定义
struct cdev { struct kobject kobj; //每个cdev都是一个kobject struct module *owner; //指向实现驱动的模块 const struct file_operations *ops; //操作这个字符设备的方法 struct list_head list; //与cdev对应的字符设备文件的inode->i_devices的链表头 dev_t dev; //起始的设备号 unsigned int count; //设备号的范围,也可以用于计数等,起始就是一个普通的变量 };
cdev结构体的定义在linux/cdev.h中,这个结构体的定义是用于描述一个设备驱动
注册函数相关的函数
cdev_alloc:给cdev结构体分配内存(指针实例化)
cdev_init:绑定cdev和file_operations
cdev_add:注册设备
cdev_del:注销设备
3:dev_t类型
dev_t类型其本质就是一个unsigned int 类型的变量,这个变量用于存放主次设备号,比如高16位存放主设备号,低16位存放次设备号,具体哪些位用来存放主设备号,哪些位用来存放次设备号要看具体的定义。
4:设备号相关的三个宏
MKDEV:由主次设备号换算得到一个设备号
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) ma:主设备号 mi:次设备号
MAJOR:从设备号中取出主设备号
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
MINOR:从设备号中取出次设备号
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。