HAL は、ハードウェア ベンダーが実装する標準インターフェースを定義することで、下位レベルのドライバ実装に Android が依存しないようにするものです。HAL を使用すると、上位レベルのシステムに影響や変更を加えることなく、機能を実装できます。このページでは、以前のアーキテクチャについて説明します。このアーキテクチャは Android 8.0 ではサポートされなくなりました。Android 8.0 以上については、HAL の概要をご覧ください。
![HAL コンポーネント](https://source.android.google.cn/static/docs/core/architecture/images/ape_fwk_hal.png?authuser=4&hl=ja)
図 1. HAL コンポーネント
プロダクトが特定のハードウェアを提供する場合、それに対応する HAL(およびドライバ)を実装する必要があります。HAL 実装は通常、共有ライブラリ モジュール(.so
ファイル)に組み込まれますが、HAL 実装とデバイス ドライバ間の標準的な通信は必須ではありません。状況に合わせて実装できます。ただし、Android システムがハードウェアと正しく通信できるようにするには、各ハードウェア固有の HAL インターフェースで定義されているコントラクトを遵守する必要があります。
HAL が予測可能な構造となるように、各ハードウェア固有の HAL インターフェースには hardware/libhardware/include/hardware/hardware.h
に定義されたプロパティがあります。このインターフェースにより、Android システムは正しいバージョンの HAL モジュールを一貫した方法で読み込むことができます。HAL インターフェースには、モジュールとデバイスの 2 つのコンポーネントがあります。
HAL モジュール
1 つのモジューがパッケージ化された HAL 実装を表し、共有ライブラリ(.so file
)として保存されます。hardware/libhardware/include/hardware/hardware.h
ヘッダー ファイルで、モジュールを表す構造体(hw_module_t
)を定義し、モジュールのバージョン、名前、作成者などのメタデータを指定します。Android は、このメタデータを使用して、HAL モジュールを正しく検出して読み込みます。
さらに、hw_module_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 オーディオ デバイス、または Bluetooth 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>
の一般的なパターンに従います。