旧版 HAL

HAL 定义了一个供硬件供应商实现的标准接口,使 Android 能够与较低级别的驱动程序实现脱钩。使用 HAL 允许您在不影响或修改更高级别系统的情况下实现功能。本页介绍的是旧版架构,自 Android 8.0 起已不再受支持。对于 Android 8.0 及更高版本,请参阅 HAL 概述

HAL components

图 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 的指针,该结构体包含指向模块的 open 函数的指针。此 open 函数用于启动与硬件的通信,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” broadly 指的是所有 Android 8.0 之前的 HAL(在 Android 8 中已弃用)。大多数 Android 系统接口(相机、音频、传感器等)都在 `hardware/libhardware/include/hardware` 下定义,并具有粗略的版本控制和大致稳定的 ABI。一些子系统(包括 Wi-Fi、无线接口层和蓝牙)在 `libhardware_legacy` 中或散布在整个代码库中具有其他非标准化接口。旧版 HAL 从未提供硬稳定性保证。