SDV trên QNX

Chúng tôi kiểm thử nội bộ SDV trên phần cứng. Chúng tôi sử dụng QVM trên QNX để ảo hoá. Chúng tôi chia sẻ tất cả các mục tiêu, tài liệu và cấu hình dưới dạng mẫu.

Điều kiện tiên quyết

Trang này giả định QNX đã được định cấu hình trước và không bao gồm các bước để tạo, định cấu hình hoặc flash QNX trên phần cứng.

Trang này giả định rằng bạn đang chạy QNX trên phần cứng arm64, đồng thời tạo và sử dụng các mục tiêu _arm64 của SDV.

Thành phần bắt buộc

  • Một blob cây thiết bị (DTB) để xác định phần cứng ảo
  • Nhân hệ điều hành Linux để sử dụng
  • Một ổ đĩa RAM kết hợp bao gồm tất cả các thuộc tính khởi động ổ đĩa RAM
  • Một quy trình chuyển giao chuỗi DICE để xác thực SDV VM
  • Tất cả các phân vùng ổ đĩa của hệ thống
  • Cấu hình QVM của máy ảo

Blob cây thiết bị (DTB)

QVM tạo hầu hết các blob cây thiết bị (DTB) dựa trên cấu hình của nó. Do đó, DTB có thể ở mức tối thiểu:

/*
 * 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 sử dụng Hình ảnh hạt nhân chung (GKI) và bạn có thể sử dụng trực tiếp đầu ra của bản dựng.

Ramdisk

Thông tin về ramdisk phải bao gồm các ramdisk mà Android tạo và các thuộc tính khởi động. Vì QNX không hỗ trợ trình tải khởi động theo mặc định, nên bạn phải tạo một ramdisk có định dạng dữ liệu dự kiến.

Bạn có thể thực hiện việc này bằng tập lệnh Python sau đây. Tập lệnh này sẽ nối nhiều ramdisk và thêm bootconfig (là tệp vendor-bootconfig.img) ở định dạng dự kiến:

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')

Chuỗi DICE

Trong hệ thống sản xuất, hệ thống máy chủ và trình tải khởi động sẽ tạo chuỗi DICE một cách linh động trong quá trình khởi động và cung cấp chuỗi DICE cho khách để xác minh rằng hình ảnh có thể tin cậy. Vì yêu cầu này có thể khiến các quy trình kiểm thử và phát triển trở nên phức tạp, nên bạn sẽ tải một ảnh chụp nhanh chuỗi DICE.

Để tạo các tệp dice_handover_instance*, hãy sử dụng mọi bản dựng SDV Cuttlefish. Ví dụ:

lunch sdv_core_cf-trunk_staging-userdebug
m
cp $OUT/product/etc/dice_handover_instance* <GUEST>/test_dice_handover

Đĩa

QVM hỗ trợ nhiều định dạng cho ổ đĩa ảo; cấu hình tham chiếu của chúng tôi sử dụng một tệp hình ảnh đĩa chứa tất cả các phân vùng. bpttool có thể tạo các ổ đĩa đó nhưng không được phát triển tích cực trong Android.

Cấu hình QVM

Cấu hình QVM đặt cấu hình và trỏ đến các tệp khác nhau. Chúng tôi cung cấp các cấu hình mẫu sau:

Câu hỏi thường gặp

H: adb không kết nối được với máy ảo của tôi. Tôi có thể làm gì?

Đáp: Trong chế độ thiết lập này, adb sử dụng Ethernet để kết nối với VM của bạn. Bạn cần có cấu hình chuyển tiếp cổng trên QNX để chuyển tiếp các yêu cầu đến khách trên cổng 5555. Bạn cần kết nối với hệ thống máy chủ. Ngoài ra, bạn cũng có thể định cấu hình một cầu nối đến máy ảo và kết nối trực tiếp với cầu nối đó.

Hỏi: Nhật ký hệ thống cho thấy IServiceRegistrationAgent bị thiếu. Vì sao lại như vậy?

Đáp: Tính năng khám phá dịch vụ dựa trên chế độ thiết lập trình liên kết và độ tin cậy hoạt động đầy đủ. Hãy xác minh rằng OpenDICE đã được tải thành công và HwBinder không hiển thị lỗi trong quá trình khởi động. Nếu những lỗi đó không hoạt động, trước tiên bạn cần phải khắc phục chúng.

Hỏi: init_open_dice không thành công. Điều gì đã xảy ra?

Đáp: Các tập lệnh khởi động sẽ tải thông tin tin cậy trong quá trình khởi động và xoá vị trí bộ nhớ. Xác minh trong cấu hình QVM rằng cấu hình cmdline và dữ liệu được chia sẻ trong vị trí bộ nhớ phù hợp với nhau. Ngoài ra, hãy xác minh rằng vị trí bộ nhớ trong trình điều khiển, cấu hình QVM và DTB khớp nhau, đồng thời vị trí bộ nhớ có thể ghi.