近日稍微對Android中的驅動開發作了一些簡要的瞭解,稍稍理清了一下Android驅動開發的套路,總結一下筆記。linux
HAL:Hardware Abstract Layer 硬件抽象層,因爲Linux Kernel須要遵循GPL開源協議,硬件廠商爲了保護本身硬件方面的各項參數不被外泄,而一個設備的驅動程序包含了硬件的一些重要參數,因此驅動的開源勢必會使硬件廠商蒙受損失,Google爲了保護硬件廠商的利益,因此在Android系統中加入了HAL層,在HAL層中沒必要遵循GPL協議,因此代碼能夠封閉。
因此若是硬件驅動開源的寫在Kernel裏,Framework直接調用,而不肯意開源的就寫在HAL層裏,實現閉源。框架
那究竟HAL怎樣實現閉源的呢?咱們來畫個簡圖.(注意:本文只提供攥寫驅動的大體思路,不對細節代碼負責。) 函數
一,編寫驅動期以及LoadingTime:
編寫驅動分爲兩個部分,一個是HAL層的驅動代碼,一個是Kernel層的驅動代碼。3d
1,HAL框架提供了三個結構體,分別爲hw_device_t , hw_module_t ,hw_module_methods_t。
編寫HAL層驅動首先要依據這三個結構體做擴展,咱們建立本身驅動的device_t,module_t代碼,而且寫hw_module_methods_t這個結構體中方法的實現代碼,這個部分叫作HAL Stub,編寫此部分驅動分爲三個步驟:
第一,建立myDeviceModel實例,第二,將hw_module_methods_t指針設定給myDeviceModel,實現hw_module_methods_t這個函數表裏函數的代碼.指針
2,在Kernel層框架一樣提供了多個結構體(module,file,file_operations,cdev),咱們能夠對系統提供的結構體進行擴展,或者直接使用系統的結構體。這個部分叫作Linux Kernel Stub,編寫此部分代碼分爲多個步驟:第一,建立myFile實例,第二 設定file_operations指針給myFile,第三 寫file_operations這個函數表中函數的實現代碼即開源部分代碼,第四,建立myDeviceModule裝配 cdev與myFile。blog
3,寫完之後編譯系統即將驅動封裝載入系統中,裝在過程首先會調用myDeviceModule的init,完成內核stub的載入,Hal層完成了對myDevice的建立.開發
二,調用驅動期(RunTime):
上面提到在HAL層咱們編寫了HAL_STUB部分,咱們來分析下系統究竟怎麼調用到硬件的,首先咱們使用HAL框架爲咱們提供的函數get到咱們寫的HALStub層的myDeviceModule,經過myDeviceModule獲取到myDevice,調用myDevice的setData或者getData方法,而後調用封閉代碼區的函數,封閉代碼區會調用systemCall調用linux內核的read(),write()函數,read(),write()往下就是硬件了。get
總結:HALStub與KernelSutb部分爲廠商開源部分,mydevice.so爲閉源部分.本文只是對驅動開發思路以及代碼執行流程做了個簡介,若有錯誤的地方還請指正。
it