對應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裝置已經出落成來一個亭亭玉立的美少女了,注意了,哥們,她現在還是單身的。接下來要做的事,嘿嘿,想必大家會比我更清楚了。網名為“洞房不敗”的兄弟開口了:“難道是要把她賣出去”,兄弟高雅點行不,不叫賣,那叫嫁,預知她是下嫁何家,請聽下回分解。