对应input core,前面我一直在夸她的好,对于一个大家都不认识的家伙,我这样说她,是不是显的特虚,好了,为了证明她并不是那么的虚,我不得不拿出前面第二节中出现过的两行代码来看看:
akm->input_dev = input_allocate_device();
err = input_register_device(akm->input_dev);
没有错,这正是我们要把akm实现为一个input 设备的仅有的几行代码中的两行。
第一行,申请一个input设备:在内核中分配相应的内存空间,并初始化它。
第二行,把这个input设备注册到linux内核中,从此这个设备在内核中生根发芽,快乐幸福的和他的handler过着属于自己的小日子(虽然handler不一定属于她一个人,不过她不在乎)。
作为一个男人,我还是得负责任为我们的input core说明一下,input_allocate_device()和input_register_device();都来自我们的 input core。现在知道她的伟大了吧。你看看,我们写一个input设备驱动本来就那么几行代码,而这仅有的几行代码中还调用了来自内核的函数。我不得不说,input core ,你真给力。
好了,我们先来研究一下第一个函数 input_allocate_device()。(linux内核源码目录linux-2.6.29/drivers/input/input.c文件中)
struct input_dev *input_allocate_device(void)
{
1 struct input_dev *dev;
2 dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
3 if (dev) {
4 dev->dev.type = &input_dev_type;
5 dev->dev.class = &input_class;
6 device_initialize(&dev->dev);
7 mutex_init(&dev->mutex);
8 spin_lock_init(&dev->event_lock);
9 INIT_LIST_HEAD(&dev->h_list);
10 INIT_LIST_HEAD(&dev->node);
12 __module_get(THIS_MODULE);
}
15 return dev;
}
第1行,申明一个input_dev结构体变量;
第2行,kzalloc()一个陌生的家伙,它其实等于kmalloc+memset。看到kmalloc相信大家觉得眼熟,没错,他的弟弟就是malloc,而kmalloc对应于内核空间的内存分配函数。好了,第二行代码的意思相信大家也明白了:在内核空间开辟一段大小为sizeof(struct input_dev)大小的内存区,并把它初始化为0。后面的GFP_KERNEL为分配的标志,即为一个常规的内存分配,类似的还有GFP_DMA,表示分配的内存能供dma使用,GFP_ATOMIC分配内存时,不允许睡眠,一般用在中断中,大家想想,如果在一个中断处理程序中,使用GFP_KERNEL标志分配内存,发现内存不足,就一直睡在那儿等待,你受得了吗(敲了一下键盘,发现过了2分钟系统才反应过来,相信这严重影响到了你和漂亮mm网聊的兴趣了)所以在中断处理函数中我们不能使用GFP_KERNEL标志分配内存。
分配到内存后,用dev指向这段内存。
第3行,判断内存分配是否成功,若成功,则进入到4—12行的对dev的初始化工作。否则,咱们啥也别说了,说了也白说,退出,走人。
第4到6行,对input设备的内嵌dev设备进行初始化。
第7到8行,初始化该dev的互斥量和锁,为防止对dev的并发访问。
第9、10两行,对input设备中的两个链表结构头进行初始化。
好了,此函数分析到此,一旦顺利进行,则该input设备已经出落成来一个亭亭玉立的美少女了,注意了,哥们,她现在还是单身的。接下来要做的事,嘿嘿,想必大家会比我更清楚了。网名为“洞房不败”的兄弟开口了:“难道是要把她卖出去”,兄弟高雅点行不,不叫卖,那叫嫁,预知她是下嫁何家,请听下回分解。