Wir testen SDV intern auf Hardware. Für die Virtualisierung verwenden wir QVM auf QNX. Wir stellen alle Ziele, Dokumentationen und Konfigurationen als Beispiele zur Verfügung.
Vorbereitung
Auf dieser Seite wird davon ausgegangen, dass QNX vorkonfiguriert ist. Die Schritte zum Erstellen, Konfigurieren oder Flashen von QNX auf Hardware sind nicht enthalten.
Auf dieser Seite wird davon ausgegangen, dass Sie QNX auf arm64-Hardware ausführen und die _arm64-Ziele von SDV erstellen und verwenden.
Erforderliche Komponenten
- Ein Gerätebaum-Blob (Device Tree Blob, DTB) zum Definieren der virtuellen Hardware
- Ein Linux-Kernel
- Eine kombinierte Ramdisk mit allen Ramdisk-Booteigenschaften
- Eine Übergabe einer DICE-Kette für die SDV-VM-Authentifizierung
- Alle Festplattenpartitionen des Systems
- Eine QVM-Konfiguration der VM
Gerätebaum-Blob (DTB)
QVM generiert den Großteil des Gerätebaum-Blobs (DTB) basierend auf seiner Konfiguration. Daher kann der DTB minimal sein:
/*
* 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>;
};
};
};
Kernel
SDV verwendet das generische Kernel-Image (Generic Kernel Image, GKI). Sie können die Ausgabe direkt aus einem Build verwenden.
Ramdisk
Die Ramdisk-Informationen sollten die verschiedenen Ramdisks enthalten, die von Android generiert werden, sowie die Booteigenschaften. Da QNX standardmäßig keinen Bootloader unterstützt, müssen Sie eine Ramdisk mit dem erwarteten Datenformat generieren.
Dazu können Sie das folgende Python-Skript verwenden, das mehrere Ramdisks verknüpft und die Bootkonfiguration (die Datei vendor-bootconfig.img) im erwarteten Format hinzufügt:
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-Kette
In einem Produktionssystem erstellen das Hostsystem und der Bootloader die DICE-Kette dynamisch während des Bootvorgangs und stellen dem Gast eine DICE-Kette zur Verfügung, um zu bestätigen, dass das Image vertrauenswürdig ist. Da diese Anforderung Test- und Entwicklungsabläufe komplizieren kann, laden Sie stattdessen einen Snapshot der DICE-Kette.
Verwenden Sie einen beliebigen SDV-Cuttlefish-Build, um die Dateien dice_handover_instance* zu generieren.
Beispiel:
lunch sdv_core_cf-trunk_staging-userdebug
m
cp $OUT/product/etc/dice_handover_instance* <GUEST>/test_dice_handover
Laufwerk
QVM unterstützt mehrere Formate für ein virtuelles Laufwerk. In unserer Referenzkonfiguration wird eine Laufwerk-Image-Datei verwendet, die alle Partitionen enthält. Mit bpttool können diese Laufwerke generiert werden, es wird aber nicht aktiv in Android entwickelt.
QVM-Konfiguration
Die QVM-Konfiguration legt die Konfiguration fest und verweist auf die verschiedenen Dateien. Wir stellen die folgenden Beispielkonfigurationen zur Verfügung:
Häufig gestellte Fragen
F: adb kann keine Verbindung zu meiner VM herstellen. Was kann ich tun?
A: Bei dieser Einrichtung verwendet adb Ethernet, um eine Verbindung zu Ihrer VM herzustellen. Sie benötigen eine Portweiterleitungskonfiguration auf QNX, die Anfragen an Gäste auf Port 5555 weiterleitet. Sie müssen eine Verbindung zum Hostsystem herstellen. Alternativ können Sie auch eine Bridge zur VM konfigurieren und direkt eine Verbindung zu ihr herstellen.
F: Im Systemlog wird angezeigt, dass IServiceRegistrationAgent fehlt. Woran liegt das?
A: Service Discovery setzt eine voll funktionsfähige Vertrauens- und Binder-Einrichtung voraus. Prüfen Sie, ob OpenDICE erfolgreich geladen wurde und HwBinder beim Start keine Fehler anzeigt. Wenn diese nicht funktionieren, müssen Sie sie zuerst beheben.
F: init_open_dice schlägt fehl. Was ist passiert?
A: Die Startskripts laden die Vertrauensinformationen beim Start und löschen den Speicherort. Prüfen Sie in Ihrer QVM-Konfiguration, ob die Befehlszeilenkonfiguration und die weitergegebenen Daten am Speicherort zusammenpassen. Prüfen Sie außerdem, ob der Speicherort im Treiber, in der QVM-Konfiguration und im DTB übereinstimmt und ob der Speicherort beschreibbar ist.