标签:cdev_add函数详解
图解cdev_add()函数
在写字符驱动的时候需要使用内核提供的cdev_add()函数来想kobj_map添加自己的cdev结构体.
1.当执行完cdev_add()函数之后.我们最终形成的结构如上.它是一个hash链表结构.
那么hash值是谁呢.这个hash只提取的是一个主设备号,最大值254.
2.在添加新的设备的时候.我们会先使用主设备号%255得到一个数组下标,然后直接访问下标中的
structprobe结构体类型的指针的地址.
3. structprobe结构体类型的指针的地址.给了一个二级指针s.
4.接下来分两种情况:
4.1.这个地址上的值为空的话.也就是(*s)==NULL的话.或者(*s)->range < range 结束循环.
直接将(*s)赋值给p→next ,也就是讲p->next= NULL;如何修改(*s)的值,修改地址.
我们需要将在堆中分配的prob结构p的挂到单链表中,也就是要将prob的值修改成p的地址.
那么我们就需要用到在s中保存的prob的地址.通过这个地址.来修改.prob的值.
也就是修改一级指针的正本.
int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, struct module *module, kobj_probe_t *probe, int (*lock)(dev_t, void *), void *data) { unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; unsigned index = MAJOR(dev); unsigned i; struct probe *p; if (n > 255) n = 255; p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL); if (p == NULL) return -ENOMEM; for (i = 0; i < n; i++, p++) { p->owner = module; p->get = probe; p->lock = lock; p->dev = dev; p->range = range; p->data = data; } mutex_lock(domain->lock); for (i = 0, p -= n; i < n; i++, p++, index++) { //找到和主设备号对应的位置的probe的指针.或者这个指针的地址. struct probe **s = &domain->probes[index % 255]; //判断*s是否为空.如果为空停止循环. 或者超出范围就停止循环. while (*s && (*s)->range < range) //否则将s = &(*s)->next;直到s为空.也就是找到链表的尾部. s = &(*s)->next; //如果链表中没有元素,讲 p->next = *s;就是将p->next = NULL; //然后改变一级指针的正本也就是 *s = p; p->next = NULL; *s = p; p->next = *s; *s = p; } mutex_unlock(domain->lock); return 0; } //将 cdev添加到kobj_map中,这个map它是一个hash的单链表.
标签:cdev_add函数详解
原文地址:http://blog.csdn.net/shaohuazuo/article/details/42343267