레거시 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은 강력한 안정성을 보장하지 않습니다.