舊版 HAL

HAL 會定義硬體供應商可實作的標準介面,讓 Android 不必瞭解較低層級的驅動程式實作方式。使用 HAL 可讓您導入功能,而不影響或修改高階系統。本頁說明舊版架構,自 Android 8.0 起已不再支援。如果是 Android 8.0 以上版本,請參閱 HAL 總覽

HAL 元件

圖 1. HAL 元件

您必須為產品提供的特定硬體實作對應的 HAL (和驅動程式)。HAL 實作通常會內建於共用程式庫模組 (.so 檔案),但由於 Android 並未規定 HAL 實作與裝置驅動程式之間的標準互動方式,因此您可以根據情況採取最適當的做法。不過,為了讓 Android 系統正確與硬體互動,您必須遵守每個硬體專屬 HAL 介面中定義的合約。

為確保 HAL 具有可預測的結構,每個硬體專屬 HAL 介面都具有在 hardware/libhardware/include/hardware/hardware.h 中定義的屬性。這個介面可讓 Android 系統以一致的方式載入正確版本的 HAL 模組。HAL 介面包含兩個元件:模組和裝置。

HAL 模組

模組代表已封裝的 HAL 實作項目,會儲存為共用程式庫 (.so file)。hardware/libhardware/include/hardware/hardware.h 標頭檔案定義的結構體 (hw_module_t) 代表模組,並包含模組的版本、名稱和作者等中繼資料。Android 會使用這項中繼資料來正確尋找及載入 HAL 模組。

此外,hw_module_t 結構體包含指向另一個結構體 hw_module_methods_t 的指標,而 hw_module_methods_t 則包含指向模組開放函式的指標。這個開放函式可用於與 HAL 用於做為抽象化的硬體啟動通訊。每個硬體專屬 HAL 通常會擴充一般 hw_module_t 結構體,並提供該特定硬體的其他資訊。舉例來說,在相機 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 並建立模組結構體時,您必須將其命名為 HAL_MODULE_INFO_SYM。以下是 Nexus 9 音訊 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,
    },
};

HAL 裝置

裝置會抽象化產品的硬體。舉例來說,音訊模組可以包含主要音訊裝置、USB 音訊裝置或藍牙 A2DP 音訊裝置。

裝置由 hw_device_t 結構體表示。與模組類似,每種裝置類型都會定義一般 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 參考文件,以及各個 HAL 的個別操作說明。

建構 HAL 模組

HAL 實作會建構到模組 (.so) 檔案中,並在適當情況下由 Android 動態連結。您可以為每個 HAL 實作項目建立 Android.mk 檔案,並指向來源檔案,藉此建構模組。一般來說,共用程式庫的名稱必須採用特定格式,才能正確找到並載入。命名架構會因模組而異,但都遵循 <module_type>.<device_name> 的一般模式。

舊版 HAL

「舊版 HAL」一詞廣義上是指所有 Android 8.0 之前的 HAL (已在 Android 8 淘汰)。大部分的 Android 系統介面 (相機、音訊、感應器等) 都定義在 `hardware/libhardware/include/hardware` 下,並具有大致的版本控制和大致穩定的 ABI。部分子系統 (包括 Wi-Fi、無線電介面層和藍牙) 在 `libhardware_legacy` 中或整個程式碼庫中穿插了其他非標準介面。舊版 HAL 從未提供嚴格的穩定性保證。