Android本質上是基於Linux核心的系統,也就是說Android就是一種Linux作業系統。只不過大多數時候都會運行在ARM架構的裝置上,例如,Android手機、平板等。Android驅動實際上就是Linux驅動,只是這裡使用Android深度探索(卷1):安裝C/C++交叉編譯環境 介紹的交叉編譯器將Linux驅動編譯成了ARM架構的,所以驅動可以安裝在Android模擬器、Android手機(需要root)或平板上(這些裝置 都要使用給予ARM架構的CPU),當然,使用傳統的GCC也可以編譯成X86架構的驅動(並不需要修改代碼),這樣也可以在Ubuntu Linux上安裝Linux驅動。
本文及後面幾篇文章主要介紹如何利用Android模擬器和S3C6410開發板開發給予ARM架構的Linux驅動,當然,測試的環境是 Android,而不是我們通常使用的Ubuntu Linux等X86架構的系統。最後會介紹通過多種方式測試這個驅動,測試方法包括命令列、NDK、Android程式(Java代碼)等,當然,在最最 後還會介紹如果將驅動嵌入到LInux核心中,這樣Android在啟動是就自動擁有了這個驅動。
想學習Android底層開發的童鞋可以通過本文完全掌握開發基於Android的LInux驅動的完整步驟。在《Android深度探索(卷1):HAL與驅動開發》隨書光碟片上有完整的實驗環境(VMWare Ubuntu Linux12.04LTS),如果嫌自己配置麻煩,可以從光碟片中複製該虛擬環境,虛擬檔案太大(3.6G),傳不上去,只能發文章了!
一、Linux驅動到底是個什麼東西
對於從未接觸過驅動開發的程式員可能會感覺Linux驅動很神秘。感覺開發起來會很複雜。其實這完全是誤解。實際上Linux驅動和普通的LinuxAPI沒有本質的區別。只是使用Linux驅動的方式與使用Linux API的方式不同而已。
在學習Linux驅動之前我們先來介紹一下Linux驅動的工作方式。如果讀者以前接觸過Windows或其他非Unix體系的作業系統,最好將它們的工作方式暫時忘掉,因為這些記憶會干擾我們理解Linux底層的一些細節。
Linux驅動的工作和訪問方式是Linux的亮點之一,同時受到了業界的廣泛好評。Linux系統將每一個驅動都映射成一個檔案。這些檔案稱為裝置檔案 或驅動檔案,都儲存在/dev目錄中。這種設計理念使得與Linux驅動進行互動就像與普通檔案進行互動一樣容易。當然,也比訪問LinuxAPI更容 易。由於大多數Linux驅動都有與其對應的裝置檔案,因此與Linux驅動交換資料就變成了與裝置檔案交換資料。例如,向Linux印表機驅動發送一個 列印命令,可以直接使用C語言函數open開啟裝置檔案,再使用C語言函數ioctl向該驅動的裝置檔案發送列印命令。
當然,要編寫Linux驅動程式還需要更進階的功能。如向印表機驅動寫入資料時,對於印表機驅動來說,需要接收這些被寫入的資料,並將它們通過PC的並 口、USB等連接埠發送給印表機。要實現這一過程就需要Linux驅動可以響應應用程式傳遞過來的資料。這就是Linux驅動的事件,雖然在C語言裡沒有事 件的概念,但卻有與事件類別似的概念,這就是回調(callback)函數。因此,編寫Linux驅動最重要的一步就是編寫回呼函數,否則與裝置檔案互動的 資料將無法得到處理。圖6-1是應用軟體、裝置檔案、驅動程式、硬體之間的關係。