社内でハードウェア上で SDV をテストしています。仮想化には QNX で QVM を使用しています。すべてのターゲット、ドキュメント、構成をサンプルとして共有しています。
前提条件
このページでは、QNX が事前に構成されていることを前提としており、ハードウェアで QNX をビルド、ビルド構成、書き込む手順は含まれていません。
このページでは、arm64 ハードウェアで QNX を実行し、SDV の _arm64 ターゲットをビルドして使用していることを前提としています。
必須のコンポーネント
- 仮想ハードウェアを定義するデバイスツリー blob(DTB)
- 使用する Linux カーネル
- すべての ramdisk ブート プロパティを含む結合された ramdisk
- SDV VM 認証用の DICE チェーンのハンドオフ
- システムのすべてのディスク パーティション
- VM の QVM 構成
デバイスツリー blob(DTB)
QVM は、構成に基づいてデバイスツリー blob(DTB)のほとんどを生成します。そのため、DTB は最小限に抑えることができます。
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/dts-v1/;
/ {
model = "Virtual Machine";
#address-cells = <2>;
#size-cells = <2>;
// This reserved-memory node specifies for the open-dice driver which memory region(s) to
// expose as /dev/open-dice<n> device(s)
reserved-memory {
// The number of u32 cells to represent the address of a memory region
#address-cells = <2>;
// The number of u32 cells to represent the size of a memory region
#size-cells = <2>;
ranges;
// The unit address (after the @) must match the address in the reg property
dice@D1C30000 {
// The open-dice driver receives this device tree node based on this
// property.
compatible = "google,open-dice";
no-map;
// The address and the size of the memory region that is passed to the
// open-dice driver.
// First two hex numbers (cells) represent the address of the memory region,
// the last two represent its size (4K, in this case).
reg = <0x0 0xD1C30000 0x0 0x1000>;
};
};
};
カーネル
SDV は汎用カーネル イメージ(GKI)を使用しており、ビルドの出力を直接使用できます。
RAM ディスク
RAM ディスク情報には、Android が生成するさまざまな RAM ディスクとブート プロパティを含める必要があります。QNX はデフォルトでブートローダーをサポートしていないため、想定されるデータ形式で ramdisk を生成する必要があります。
これを行うには、次の Python スクリプトを使用します。このスクリプトは、複数の ramdisk を連結し、bootconfig(vendor-bootconfig.img ファイル)を想定される形式で追加します。
def create_qnx_ramdisk(output: io.BytesIO,
ramdisks: Sequence[io.BytesIO],
bootconfig: Optional[io.BytesIO]):
BUFFER_SIZE = 4096
for ramdisk in ramdisks:
while buf := ramdisk.read(BUFFER_SIZE):
output.write(buf)
# Kernel looks for bootconfig at the end of ramdisk.
if bootconfig:
bootconfig_checksum = 0
bootconfig_size = 0
while buf := bootconfig.read(BUFFER_SIZE):
bootconfig_checksum = (bootconfig_checksum + sum(buf)) & 0xFFFFFFFF
bootconfig_size += len(buf)
output.write(buf)
output.write(struct.pack('II', bootconfig_size, bootconfig_checksum))
output.write(b'#BOOTCONFIG\n')
DICE チェーン
本番環境システムでは、ホストシステムとブートローダーがブートプロセス中に DICE チェーンを動的に構築し、ゲストに DICE チェーンを提供して、イメージが信頼できることを検証します。この要件によりテストと開発フローが複雑になる可能性があるため、代わりに DICE チェーン スナップショットを読み込みます。
dice_handover_instance* ファイルを生成するには、SDV Cuttlefish ビルドを使用します。次に例を示します。
lunch sdv_core_cf-trunk_staging-userdebug
m
cp $OUT/product/etc/dice_handover_instance* <GUEST>/test_dice_handover
ディスク
QVM は仮想ディスクの複数の形式をサポートしています。リファレンス構成では、すべてのパーティションを含むディスク イメージ ファイルを使用します。bpttool はこれらのディスクを生成できますが、Android 内で積極的に開発されているわけではありません。
QVM の構成
QVM 構成は構成を設定し、さまざまなファイルを指します。次の構成例を示します。
よくある質問
Q: adb が VM に接続できません。対処方法を教えてください。
A: この設定では、adb はイーサネットを使用して VM に接続します。QNX で、ポート 5555 のゲストにリクエストを転送するポート転送構成が必要です。ホストシステムに接続する必要があります。別の方法として、VM へのブリッジを構成して、直接接続することもできます。
Q: システムログに IServiceRegistrationAgent が見つからないと表示されます。なぜですか?
A: サービス ディスカバリは、完全に機能する信頼とバインダーの設定に依存しています。OpenDICE が正常に読み込まれ、起動中に HwBinder がエラーを表示していないことを確認します。それらが機能していない場合は、まずそれらを修正する必要があります。
Q: init_open_dice が失敗します。何が起こったのか。
A: 起動スクリプトは起動時に信頼情報を読み込み、メモリ位置を消去します。QVM 構成で、コマンドライン構成とメモリ位置の共有データが一致していることを確認します。また、ドライバ、QVM 構成、DTB のメモリ位置が一致しており、メモリ位置が書き込み可能であることを確認します。