旧版 HAL

HAL 可定义一个标准接口以供硬件供应商实现,这样可让 Android 兼容较低级别的驱动程序实现。借助 HAL,您可以在不影响或更改更高级别系统的情况下,顺利实现相关功能。本页介绍了自 Android 8.0 起不再支持的旧版架构。对于 Android 8.0 及更高版本,请参阅 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 的指针,后面这个结构体包含指向相应模块的 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>