Microdroid vendor modules

Starting with Android V it is possible to start a Microdroid VM with a vendor-prodived kernel modules. This feature is part of the bigger device assignment effort.

The vendor kernel modules should be packaged inside a microdroid-vendor.img dm-verity protected partition, inside a Microdroid VM this will be mounted as /vendor partition.

Currently the following features are supported:

  • Kernel modules;
  • init .rc scripts with basic triggers (e.g. on early-init);
  • ueventd.rc file;
  • /vendor/etc/selinux/vendor_file_contexts file.

Additionallity, starting with android15-6.6 it is possible to start a Microdroid VM with GKI as guest kernel. This is required when launching a Microdroid VM with vendor provided kernel modules.

Note: in Android V, the ‘Microdroid vendor modules’ is considered an experimental feature to provide our partners a reference implementation that they can start integrating with to flesh out missing pieces. We do not recommened launching user-facing features that depend on using vendor modules in a pVM.

Integrating into a product

You can define microdroid vendor partition using android_filesystem soong module, here is an example:

android_filesystem {
    name: "microdroid_vendor_example_image",
    partition_name: "microdroid-vendor",
    type: "ext4",
    file_contexts: "file_contexts",
    use_avb: true,
    avb_private_key: ":microdroid_vendor_example_sign_key",
    mount_point: "vendor",
    deps: [
        "microdroid_vendor_example_ueventd",
        "microdroid_vendor_example_file_contexts",
        "microdroid_vendor_example_kernel_modules",
        "microdroid_vendor_example.rc",
    ],
}

prebuilt_etc {
    name: "microdroid_vendor_example",
    src: ":microdroid_vendor_example_image",
    relative_install_path: "avf/microdroid",
    filename: "microdroid_vendor.img",
    vendor: true,
}

In order to integrate the microdroid vendor partition into a product, add the following lines to the corresponding device makefile:

PRODUCT_PACKAGES += microdroid_vendor_example
MICRODROID_VENDOR_IMAGE_MODULE := microdroid_vendor_example

Note: it is important that the microdroid-vendor.img is installed into /vendor/etc/avf/microdroid/microdroid_vendor.img on the device.

Launching a Microdroid VM wirth vendor partition

Non-protected VMs

You can launch a non-protected Microdroid VM with vendor partition by adding the --vendor argument to the /apex/com.android.virt/bin/vm run-app or /apex/com.android.virt/bin/vm run-microdroid CLI commands, e.g.:

adb shell /apex/com.android.virt/bin/vm/run-microdroid \
  --debug full \
  --vendor /vendor/etc/avf/microdroid/microdroid_vendor.img

On the Android host side, the virtmgr will append the vendor_hashtree_descriptor_root_digest property to the /avf node of the guest device tree overlay. Value of this property will contain the hashtree digest of the microdroid_vendor.img provided via the --vendor argument.

Inside the Microdroid guest VM, the first_stage_init will use the /proc/device-tree/avf/vendor_hashtree_descriptor_root_digest to create a dm-verity device on top of the /dev/block/by-name/microdroid-vendor block device. The /vendor partition will be mounted on top of the created dm-verity device.

TODO(ioffe): create drawings and add them here.

Protected VMs

As of now, only debuggable Microdroid pVMs support running with the Microdroid vendor partition, e.g.:

adb shell /apex/com.android.virt/bin/vm/run-microdroid \
  --debug full \
  --protected \
  --vendor /vendor/etc/avf/microdroid/microdroid_vendor.img

The execution flow is very similar to the non-protected case above, however there is one important addition. The pvmfw binary will use the VM reference DT blob passed from the Android Bootloader (ABL), to validate the guest DT overlay passed from the host.

See Changes in Android Bootloader section below for more details.

Reflecting microdroid vendor partition in the guest DICE chain

The microdroid vendor partition will be reflected as a separate Microdroid vendor node in the Microdroid DICE chain.

TODO(ioffe): drawing of DICE chain here.

This node derivation happens in the derive_microdroid_vendor_dice_node, which is executed by first_stage_init. The binary will write the new DICE chain into the /microdroid_resources/dice_chain.raw file, which will be then read by microdroid_manager to derive the final Microdroid payload DICE node.

TODO(ioffe): another drawing here.

Changes in the Android Bootloader

In order for a Microdroid pVM with the /vendor/etc/avf/microdroid/microdroid_vendor.img to successfully boot, the ABL is required to pass the correct value of the /vendor/etc/avf/microdroid/microdroid_vendor.img hashtree digest in the vendor_hashtree_descriptor_root_digest property of the /avf/reference node.

The MICRODROID_VENDOR_IMAGE_MODULE make variable mentioned in the section above configures build system to inject the value of the microdroid-vendor.img hashtree digest into the com.android.build.microdroid-vendor.root_digest property of the footer of the host's vendor.img.

The Android Bootloader can read that property when construction the VM reference DT blob passed to pvmfw.

GKI as Microdroid guest kernel

In order to enable running Microdroid with GKI as guest kernel, specify the PRODUCT_AVF_MICRODROID_GUEST_GKI_VERSION variable in a product makefile:

PRODUCT_AVF_MICRODROID_GUEST_GKI_VERSION := android15_66

Note: currently this will alter the content of the com.android.virt APEX by installing the corresponding GKI image into it. In the future, the GKI image will be installed on the /system_ext partition.

The following changes to the gki_defconfig were made to support running as guest kernel:

CONFIG_VIRTIO_VSOCKETS=m
CONFIG_VIRTIO_BLK=m
CONFIG_OPEN_DICE=m
CONFIG_VCPU_STALL_DETECTOR=m
CONFIG_VIRTIO_CONSOLE=m
CONFIG_HW_RANDOM_CCTRNG=m
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m
CONFIG_DMA_RESTRICTED_POOL=y