Android在設備的規格與驅動方面給了你很大的自由來實現。HAL層提供了一個標準的方式來打通Android系統層與硬件層。Android系統是開源的,因此你可以在接口和性能方面貢獻本身的力量。html
爲了保證設備維持一個高水平的質量,而且提供一個持續穩定的用戶體驗,每一個設備必須經過兼容性測試(CTS).CTS確保設備符合質量標準,用來保證app可靠的運行,而且有一個好的用戶體驗。如需瞭解更多,請看Compatiblitylinux
在將android移植到硬件以前,請花些時間從一個比較高的層次瞭解下android系統的架構。由於你的驅動和HAL層經過android進行通訊,因此瞭解android如何工做有助於你定位android源代碼各個層次的代碼。android
圖1 android系統結構api
Application framework 被開發者接觸的最多。做爲一個硬件開發者,你應該意識到,應用層的API可以映射到HAL層的接口,也可以在開發驅動的過程當中提供不少有用的信息。架構
Binder 進程內通訊機制容許應用程序框架透過進程的邊界,而且調用android system services 的代碼。這樣可以保證上層的框架代碼與底層的android system services之間的通訊。在 應用framwork層,這種通訊對開發者是透明的,這樣看起來這兩個層之間通訊是理所固然。app
應用framework層暴露的一些實際功能是經過與system services通訊來達到訪問底層硬件的目的。services是模塊化的,主要的幾個組件好比Window Manager,Search Service,Notifycation Manager.Android 包含了兩個組的service,系統(好比Window Manager,Search Service)和媒體(好比播放與錄製)框架
硬件抽象層(HAL)爲硬件廠商定義了一個標準的接口,讓廠商本身實現。同時android也能向開發者隱藏掉底層驅動的實現細節。HAL層讓開發者不影響上層系統的狀況下,開發功能。HAL的實現被打包進so文件中,而且在適當的時機被系統加載。
模塊化
圖2硬件抽象層的組件函數
你必須爲硬件提供商提供的指定的硬件實現相符合的HAL(和驅動)。HAL的實現一般是編譯到共享庫的模塊中(.so文件).Android沒有在HAL實現層與硬件層指定一個標準的通訊方式,這樣你能夠根據本身的狀況實現最好的方案。固然,爲了能讓Android系統正確的與硬件通訊,你必須遵照已有的約定,這個約定是在每一個硬件特殊指定的HAL接口中定義的。性能
每個指定的HAL接口有指定的屬性,這些屬性定義在hardware/libhardware/include/hardware/hardware.h這個文件中,這樣可以保證HAL用戶可控的結構。這個接口讓Android系統一致的加載正確版本的HAL模塊。在這裏包含了兩種一般的組件,一個module,一個device.
module 表明了你的HAL層的實現,存儲在共享的ligrary中(.so文件)。裏面包含了metadata包含了好比版本,名字,做者,這有助於幫助Android發現而且正確的加載。hardware/libhardware/include/hardware/hardware.h這個頭文件定義了一個hw_module_t結構,這個結構表明一個module,裏面包含了剛剛提到的版本,名字和做者。
另外 hw_module_t這個結構包含了一個指向一個另外hw_module_methods_t結構的指針,而hw_module_methods_t這個結構包含了了一個指針指向一個開放的方法。這個開放的方法是用來初始化HAL與硬件的通訊。每個硬件指定的HAL一般都會包含hw_module_t這個結構,用來爲硬件添加額外的信息。例如在camera HAL中,camera_module_t中包含了hw_module_t,同時包含了兩個相機指定函數的指針。
typedef struct camera_module { hw_module_t common; int (*get_number_of_cameras)(void); int (*get_camera_info)(int camera_id, struct camera_info *info); } camera_module_t;
當你實現了HAL,而且建立了一個module 結構,你必須把他命名爲HAL_MODULE_INFO_SYM,例如,這裏有了Nexus 9 audio HAL的實現
struct audio_module HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = AUDIO_MODULE_API_VERSION_0_1, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = AUDIO_HARDWARE_MODULE_ID, .name = "NVIDIA Tegra Audio HAL", .author = "The Android Open Source Project", .methods = &hal_module_methods, }, };
另一個組件device,把實際的硬件中抽象出來。例如,一個audio module可以包含一個私有的audio device,一個 USB audio device 或者一個藍牙A2DP audio device。一個device是由hw_device_t結構表明的。就跟module同樣,每種類型的device定義了一個更加詳細版本的hw_device_t,裏面包含了功能函數的指針用來實現特定的硬件功能。例如,audio_hw_device_t結構包含了媒體設備操做的函數的指針:
struct audio_hw_device {
struct hw_device_t common;
/** * used by audio flinger to enumerate what devices are supported by * each audio_hw_device implementation. * * Return value is a bitmask of 1 or more values of audio_devices_t */ uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); ... }; typedef struct audio_hw_device audio_hw_device_t;
另外除了這些標準的屬性,每個硬件指定的HAL接口都能定義本身的特性和需求。請看HAL reference documentation,這是個獨立的文檔,來介紹每一個HAL在實現特定接口時候更多的信息。
HAL的實現被編譯到modules(.so)文件中,Android系統會在適當的時機動態連接他們。你能夠經過爲每一個HAL實現建立Android.mk文件,而後指向你的源文件。一般,你的共享的libraries必須有一個格式命名,這樣他們才能被正確找到並加載。命名策略在不一樣的module中有些許的不一樣,可是他們都遵循下面的模式
要獲得更多的關於建立HAL,請看他們各自的文檔。
開發一個設備驅動跟開發一個標準的Linux設備驅動很像。Android使用的linux版本是添加了一些額外的功能,好比弱鎖(一個內存管理系統,更加好的保護內存),Binder IPC driver,還有一些對於移動手機平臺更加劇要的特性。這些額外的添加主要是爲了系統的功能,而且不會影響驅動的開發。
你可使用任何版本的內核,只要他它支持咱們須要的特性。不過,咱們仍是建議使用最近的Android 內核,有關最近的android內核相關,請看Building Kernels.