SDV روی QNX

ما SDV را به صورت داخلی روی سخت‌افزار آزمایش می‌کنیم. ما از QVM روی QNX برای مجازی‌سازی استفاده می‌کنیم. ما تمام اهداف، مستندات و پیکربندی‌ها را به عنوان نمونه به اشتراک می‌گذاریم.

پیش‌نیازها

این صفحه فرض را بر یک QNX از پیش پیکربندی شده می‌گذارد و شامل مراحل ساخت، پیکربندی یا فلش کردن QNX روی سخت‌افزار نمی‌شود.

این صفحه فرض می‌کند که شما QNX را روی سخت‌افزار arm64 اجرا می‌کنید و در حال ساخت و استفاده از تارگت‌های _arm64 مربوط به SDV هستید.

اجزای مورد نیاز

  • یک قطعه درخت دستگاه (DTB) برای تعریف سخت‌افزار مجازی
  • یک هسته لینوکس برای استفاده
  • یک ramdisk ترکیبی که شامل تمام ویژگی‌های بوت ramdisk است
  • انتقال یک زنجیره DICE برای احراز هویت SDV VM
  • تمام پارتیشن‌های دیسک سیستم
  • پیکربندی QVM از ماشین مجازی

قطعه درخت دستگاه (DTB)

QVM بیشتر قطعه کد درخت دستگاه (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) استفاده می‌کند و شما می‌توانید مستقیماً از خروجی یک نسخه ساخته شده استفاده کنید.

رمدیسک

اطلاعات ramdisk باید شامل ramdisk های مختلفی باشد که اندروید تولید می‌کند و ویژگی‌های بوت. از آنجا که QNX به طور پیش‌فرض از بوت لودر پشتیبانی نمی‌کند، شما باید یک ramdisk با فرمت داده مورد انتظار ایجاد کنید.

شما می‌توانید این کار را با اسکریپت پایتون زیر انجام دهید که چندین 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 می‌تواند این دیسک‌ها را تولید کند، اما به طور فعال در اندروید توسعه داده نشده است.

پیکربندی QVM

پیکربندی QVM پیکربندی را تنظیم می‌کند و به فایل‌های مختلف اشاره می‌کند. ما پیکربندی‌های نمونه زیر را ارائه می‌دهیم:

  • پیکربندی ماشین مجازی SDV Core
  • پیکربندی SDV Media VM
  • ماشین مجازی IVI با یکپارچه‌سازی SDV

سوالات متداول

س: adb نمی‌تواند به ماشین مجازی من متصل شود. چه کاری می‌توانم انجام دهم؟

الف) در این تنظیمات، adb از اترنت برای اتصال به ماشین مجازی شما استفاده می‌کند. شما به پیکربندی port forwarding در QNX نیاز دارید که درخواست‌ها را به ماشین‌های مهمان روی پورت ۵۵۵۵ ارسال کند. شما باید به سیستم میزبان متصل شوید. به عنوان یک جایگزین، می‌توانید یک bridge به ماشین مجازی نیز پیکربندی کنید و مستقیماً به آن متصل شوید.

س: گزارش سیستم نشان می‌دهد که IServiceRegistrationAgent وجود ندارد. چرا؟

الف) کشف سرویس به یک تنظیم کاملاً کارآمد برای trust و binder متکی است. تأیید کنید که OpenDICE با موفقیت بارگذاری شده است و HwBinder هنگام راه‌اندازی خطایی نشان نمی‌دهد. اگر این خطاها کار نمی‌کنند، ابتدا باید آنها را برطرف کنید.

س: init_open_dice با شکست مواجه شد. چه اتفاقی افتاده است؟

الف) اسکریپت‌های راه‌اندازی، اطلاعات اعتماد را در هنگام راه‌اندازی بارگذاری می‌کنند و مکان حافظه را پاک می‌کنند. در پیکربندی QVM خود تأیید کنید که پیکربندی cmdline و داده‌های مشترک در مکان حافظه با هم مطابقت دارند. همچنین تأیید کنید که مکان حافظه در درایور، پیکربندی QVM و DTB مطابقت دارند و مکان حافظه قابل نوشتن است.