기존 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 모듈

모듈은 공유 라이브러리(.so file)로 저장되는 패키징된 HAL 구현을 나타냅니다. hardware/libhardware/include/hardware/hardware.h 헤더 파일은 모듈을 나타내는 구조체(hw_module_t)를 정의하며 버전, 이름 및 모듈 작성자와 같은 메타데이터를 포함합니다. Android는 이 메타데이터를 사용하여 HAL 모듈을 찾아 올바르게 로드합니다.

또한 hw_module_t 구조체는 모듈의 Open 함수 포인터가 포함된 또 다른 구조체인 hw_module_methods_t의 포인터를 포함하고 있습니다. 이 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이라는 용어는 광범위하게 Android 8.0 이전의 모든 HAL을 의미합니다(Android 8에서 지원 중단됨). 대부분의 Android 시스템 인터페이스(카메라, 오디오, 센서 등)는 `hardware/libhardware/include/hardware` 아래에 정의되어 있으며, 간단한 버전 관리 및 대략적으로 안정적인 ABI를 제공합니다. 일부 하위 시스템(Wi-Fi, 무선 인터페이스 레이어, 블루투스 포함)은 `libhardware_legacy`에 표준화되지 않은 다른 인터페이스가 있거나 코드베이스 전반에 걸쳐 분산되어 있습니다. 레거시 HAL은 강력한 안정성을 보장하지 않습니다.