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.
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.
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.
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.
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.
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.
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