AAOS で VirtIO をサポートするために必要な変更の大半は、Android 共通カーネルの HAL 実装レベル以下での変更です。Android フレームワークは、AAOS ゲスト VM カーネルの VirtIO ドライバを使用して、ハードウェアに依存しない汎用 HAL と通信します。HAL は VirtIO プロトコルを使用して、ホスト側の VirtIO デバイスと通信します。ホスト側の VirtIO デバイスは、SoC 固有のデバイス ドライバを使用して物理 HW にアクセスできます。
VirtIO ドライバと VirtIO デバイス間の通信は、virtqueue
(DMA のようなスキャッタ ギャザーリストのリングバッファ)を使用して行われます。MMIO や PCI などの複数のトランスポートを使用して、VM 間で VirtIO メッセージを交換できます。
場合によっては、vsock
が VM 間通信に使用されます。車両 HAL、オーディオ コントロール、Dumpstate 通信は、別の VM 上のピア エージェントとの、vsock
インターフェースを介した接続を使用してサポートされます。GRPC-vsock
は、これらの標準化されていないサブシステムへのアクセスに使用されます。Android ソースツリーの GRPC が、vsock:CID:PORT_NUMBER
のアドレス形式で vsock
と連携するように変更されました。
オーディオ
仮想化 AAOS では、Android ゲスト VM が virtio-snd
を使用してオーディオにアクセスできます。
virtio-snd
によって仮想化 PCM デバイスが Android VM に提供されることで、オーディオ HAL 実装が TinyALSA ライブラリを使用して仮想化サウンド デバイスを操作できるようになります。
デフォルトのオーディオ HAL 実装は、AOSP の /device/google/trout/hal/audio/6.0
にあります。OEM は、プラットフォームに合わせて ro.vendor.trout.audiohal.{in,out}_period_{ms,count}
を変更できます。また、/device/google/trout/aosp_trout_common.mk.
のオーディオ関連変数をオーバーライドして、独自のオーディオ HAL を実装することもできます。
オーディオ コントロール HAL は、AAOS で音声フォーカスを管理します。たとえば、システムが緊急サウンドを再生しているときに、バックグラウンドで再生されている音楽をミュートする必要があります。この場合、オーディオ コントロール HAL は、音楽を再生しているアプリに通知して音楽をミュートします。仮想化システムでは、他の VM からサウンドが出力される場合があります。リファレンス実装の場合、AAOS ゲスト VM でオーディオ コントロール サーバー デーモンが実行されています。このデーモンは、GRPC-vsock
を使用して他の VM からの音声フォーカス リクエストを受信します。ホスト VM は、device/google/trout/hal/audiocontrol/2.0/libandroid_audio_controller
を使用して AAOS に音声コントロール リクエストを送信できます。libandroid_audio_controller
は音声フォーカスを保持している間、フォーカスが解放されるまで AAOS にハートビートを送信し続けます。
Bluetooth
Bluetooth の実装は次の図に基づいています。
Bluetooth ハンズフリー プロファイル
trout
で Bluetooth ハンズフリー プロファイル(HFP)を有効にするために、VirtIO サウンド デバイス仕様が拡張され、オーディオ コントロールがサポートされるようになりました。このアプローチを使用すると、ホスト / ハイパーバイザ側の VirtIO サウンド デバイスが、HFP に関連する次の 3 つのオーディオ コントロールを提供します。
hfp_enable
hfp_set_sampling_rate
hfp_volume
AAOS がゲスト VM として実行されている場合、AAOS は TinyAlsa を使用してこれらのオーディオ コントロールを設定します。HFP ユースケースを有効にするために、ホスト / ハイパーバイザはベンダー固有のルーティングと調整を適宜実行します。
Bluetooth の実装は次の図に基づいています。
Dumpstate
仮想化 AAOS のバグレポートを生成する際は、デベロッパーがシステムの全体像を把握できるように、ホスト VM 情報を含めることが重要です。これを実現するために、trout
リファレンス実装には IDumpstateDevice
HAL が実装されており、GRPC-vsock
を介してホスト VM 情報が収集されます。tar にパッケージ化されたホスト VM 情報は、バグレポートで dumpstate_board.bin
という名前で表示され、ダンプログは dumpstate_board.txt
に出力されます。
実行するコマンドの構成手順は次のとおりです。
- 以下のファイルから、構成の詳細を XML ファイル(
config.xml
など)にコピーします。<dumpstateHalConfiguration version="1.0"> <services> <service name="coqos-virtio-blk" command="/bin/journalctl --no-pager -t coqos-virtio-blk"/> <service name="coqos-virtio-net" command="/bin/journalctl --no-pager -t coqos-virtio-net"/> <service name="coqos-virtio-video" command="/bin/journalctl --no-pager -t coqos-virtio-video"/> <service name="coqos-virtio-console" command="/bin/journalctl --no-pager -t coqos-virtio-console"/> <service name="coqos-virtio-rng" command="/bin/journalctl --no-pager -t coqos-virtio-rng"/> <service name="coqos-virtio-vsock" command="/bin/journalctl --no-pager -t coqos-virtio-vsock"/> <service name="coqos-virtio-gpu-virgl" command="/bin/journalctl --no-pager -t coqos-virtio-gpu-virgl"/> <service name="coqos-virtio-scmi" command="/bin/journalctl --no-pager -t coqos-virtio-scmi"/> <service name="coqos-virtio-input" command="/bin/journalctl --no-pager -t coqos-virtio-input"/> <service name="coqos-virtio-snd" command="/bin/journalctl --no-pager -t coqos-virtio-snd"/> <service name="dumpstate_grpc_server" command="/bin/journalctl --no-pager -t dumpstate_grpc_server"/> <service name="systemd" command="/bin/journalctl --no-pager -t systemd"/> <service name="systemctl" command="/bin/systemctl status"/> <service name="vehicle_hal_grpc_server" command="/bin/journalctl --no-pager -t vehicle_hal_grpc_server"/> </services> <systemLogs> <service name="dmesg" command="/bin/dmesg -kuPT"/> </systemLogs> </dumpstateHalConfiguration>
- 起動時に、新しい XML ファイルのパスを dumpstate サーバーに渡します。次に例を示します。
--config_file my_config.xml
拡張ビューシステム(EVS)
拡張ビューシステム(EVS)は、リアビュー カメラとサラウンド ビューカメラで撮影された動画を表示するために使用されます。仮想化 AAOS では、EVS スタックは、VirtIO-video ドライバを使用する仮想化 V4L2 ストリーミング デバイスから動画ストリームにアクセスできます。
ガレージモード
詳しくは、ガレージモードとはをご覧ください。
ガレージモードの開始と終了は、車両 HAL から送信された AP_POWER_STATE_REQ
プロパティによってトリガーされます。仮想化モードでは、ガレージモードがホスト側からトリガーされます。
Android VM に仮想デバイスを提供できるように、Android VM の電源をオフにするまではホスト VM の電源をオンしておく必要があります。ホスト VM の VHAL サーバーは、シャットダウン シグナルを AAOS ゲスト VM に送信します。シグナルを受信すると、VHAL クライアントである AAOS VM はガレージモードに入り、ホスト VM をアクティブに保つためハートビート シグナルの送信を開始します。
グローバル ナビゲーション衛星システム(GNSS)
trout
1.0 では、virtio-console
経由の GNSS 仮想化のサポートが追加されています。この実装では、ホストからゲストへの未加工の測定値と位置情報の修正データの交換がサポートされます。
データ交換形式は GnssLogger アプリで使用される CSV です。リファレンス実装では、ネイティブ GNSS ドライバが利用できないためモックデータが利用可能になりますが、ネイティブ ドライバはゲスト側の変更なしで実装できます。サンプルの疑似ホスト エージェントは、trout
ソースコードの一部として提供されます。
現在の実装では、GNSS 初期化とアシスト GNSS(AGNSS)がホスト OS 環境で処理されることを想定しています。
グラフィック
AAOS が他の自動車用オペレーティング システムとともにゲスト VM として実行されている場合、Android は GPU またはディスプレイ コントローラに直接アクセスできないことがあります。この場合、Android ゲスト VM 上の Mesa または goldfish-opengl
と virtio-gpu
ドライバ、および virtio-gpu
デバイスを使用して GPU にアクセスできます。
Android ゲスト VM で、Mesa または goldfish-opengl
が OpenGLES コマンドをそれぞれ Gallium ストリームまたは自動生成された GLES ストリームにエンコードします。virtio-gpu
カーネル ドライバはトランスポートとして使用されます。ホスト側の virglrenderer
(Mesa の場合)と vulkan-cereal
(goldfish-opengl
の場合)は、既存の GPU ドライバ上でデコードされたコマンド ストリームを再生します。AAOS リファレンス プラットフォームの trout
は OpenGL ES のみをサポートしていますが、今後のリリースで Vulkan に対応する予定です。
センサー
AAOS が他の自動車用オペレーティング システムとともにゲスト VM として実行されている場合、Android はセンサーに直接アクセスできないことがあります。この場合、Android ゲスト VM の Virtio-SCMI ドライバとホスト VM の VirtIO-SCMI デバイスを使用してセンサーにアクセスします。 AAOS 仮想化リファレンス プラットフォームには、ARM ベースの SoC がセンサーにアクセスするために使用できる、HW に依存しない汎用センサー HAL が用意されています。
センサー HAL は、Linux カーネル IIO サブシステムの IIO SCMI ドライバと通信します。ARM System Control and Management Interface(SCMI)の仕様で指定されている SCMI センサー管理プロトコルを使用して、センサーの検出と構成、センサーデータの読み取り、センサー値の変更通知の受け取りを行います。
IIO SCMI ドライバは、VirtIO SCMI ドライバを使用します。VirtIO SCMI ドライバは、virtio-scmi
仕様で指定されている VirtIO トランスポート プロトコルを使用して、ホスト VM 上の VirtIO SCMI デバイスと SCMI メッセージを交換します。VirtIO SCMI デバイスは、SoC 固有のセンサー ドライバを介してセンサーに直接アクセスできます。
センサー HAL の場所
VirtIO SCMI を使用するセンサー HAL のリファレンス実装は device/google/trout/hal/sensors
にあります。
センサー HAL の構成
センサー HAL は、Android の自動車センサー座標系を遵守するために、ホスト VM から受信したセンサーデータを変更する必要がある場合があります。センサー構成のスキーマは device/google/trout/hal/sensors/2.0/config/sensor_hal_configuration.xsd
にあります。
OEM は、向きや位置などのセンサー構成を sensor_hal_configuration.xml
で指定し、ファイルを /odm/etc/sensors/
または /vendor/etc/sensors/
にコピーできます。センサー構成の例を以下に示します。
<sensorHalConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <modules> <module halName="android.hardware.sensors@2.0-Google-IIO-Subhal" halVersion="2.0"> <sensors> <sensor name="scmi.iio.accel" type="1"> <configuration> <!-- Attribute rotate denotes if HAL needs to modify the sensor data to comply with // the Android car sensor coordinate system --> <orientation rotate="true"> <!-- Attribute map denotes the indexes of data in sensor data received --> <!-- Attribute negate denotes if data needs to be negated --> <x map="0" negate="false"/> <y map="1" negate="true"/> <z map="2" negate="true"/> </orientation> <location> <!-- Attribute x, y, z denotes location of the sensor placement --> <x>10</x> <y>15</y> <z>20</z> </location> </configuration> </sensor> </sensors> </module> </modules> </sensorHalConfiguration>
車両 HAL
車両 HAL の実装は、次の 2 つのコンポーネントで構成されています。
- クライアント。仮想化 AAOS で Android が使用する API を提供します。
- サーバー。車両バス(またはエミュレータ)などのハードウェアと直接通信します。
仮想化では、VHAL サーバーはホスト VM で実行されます。VHAL クライアントとサーバーは GRPC-vsock
を介して通信します(詳細については、device/google/trout/hal/vehicle/2.0/proto/VehicleServer.proto
をご覧ください)。OEM は、通信 API をオーバーライドして、GRPC 以外のトランスポート プロトコルを使用できます。例については、device/google/trout/hal/vehicle/2.0/GrpcVehicle{Client,Server}.cpp
をご覧ください。
その他のサブシステム
VirtIO には、ブロック ストレージ、ネットワーク、コンソール、入力、ソケット、エントロピーなどのコンポーネント用に明確に定義されたインターフェースが用意されています。これらのサブシステムの場合、AAOS は virtio-blk
、virtio-input
、virtio-console
、virtio-net
などのドライバをそのまま使用します。
仮想化 AAOS のリファレンス プラットフォームでは、mac80211_hwsim
によって Wi-Fi がサポートされ、VirtWifi
ワイヤレス ネットワークが有効になっています。このネットワークでは、virtio-net
トンネルを使用してネットワーク トラフィックがホスト VM に送信されます。ホスト VM は、実際の Wi-Fi ネットワークに直接アクセスできます。