1. 程式人生 > >Android HAL層與Linux Kernel層驅動開發簡介

Android HAL層與Linux Kernel層驅動開發簡介

近日稍微對Android中的驅動開發做了一些簡要的瞭解,稍稍理清了一下Android驅動開發的套路,總結一下筆記。

這裡寫圖片描述

HAL:Hardware Abstract Layer 硬體抽象層,由於Linux Kernel需要遵循GPL開源協議,硬體廠商為了保護自己硬體方面的各項引數不被外洩,而一個裝置的驅動程式包含了硬體的一些重要引數,所以驅動的開源勢必會使硬體廠商蒙受損失,Google為了保護硬體廠商的利益,所以在Android系統中加入了HAL層,在HAL層中不必遵循GPL協議,所以程式碼可以封閉。
所以如果硬體驅動開源的寫在Kernel裡,Framework直接呼叫,而不願意開源的就寫在HAL層裡,實現閉源。

那究竟HAL怎樣實現閉源的呢?我們來畫個簡圖.(注意:本文只提供攥寫驅動的大致思路,不對細節程式碼負責。)
這裡寫圖片描述

一,編寫驅動期以及LoadingTime:
編寫驅動分為兩個部分,一個是HAL層的驅動程式碼,一個是Kernel層的驅動程式碼。

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。

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()往下就是硬體了。

總結:HALStub與KernelSutb部分為廠商開源部分,mydevice.so為閉源部分.本文只是對驅動開發思路以及程式碼執行流程作了個簡介,如有錯誤的地方還請指正。