blob: c0cba97dd50b6f97ca0a14c3dcf27a1dd75e3022 [file] [log] [blame] [view]
# Microdroid
Microdroid is a (very) lightweight version of Android that is intended to run on
on-device virtual machines. It is built from the same source code as the regular
Android, but it is much smaller; no system server, no HALs, no GUI, etc. It is
intended to host headless & native workloads only.
## Prerequisites
Any 64-bit target (either x86\_64 or arm64) is supported. 32-bit target is not
supported.
The only remaining requirement is that `com.android.virt` APEX has to be
pre-installed. To do this, add the following line in your product makefile.
```make
$(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)
```
Build the target product after adding the line, and flash it. This step needs
to be done only once for the target.
If you are using Pixel 6 and beyond or Cuttlefish (`aosp_cf_x86_64_phone`)
adding above line is not necessary as it's already done.
## Building and installing microdroid
Microdroid is part of the `com.android.virt` APEX. To build it and install to
the device:
```sh
banchan com.android.virt aosp_arm64
UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m apps_only dist
adb install out/dist/com.android.virt.apex
adb reboot
```
If your target is x86\_64 (e.g. `aosp_cf_x86_64_phone`), replace `aosp_arm64`
with `aosp_x86_64`.
## Building an app
A [vm
payload](https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/vm_payload/)
is a shared library file that gets executed in microdroid. It is packaged as
part of an Android application. The library should have an entry point
`AVmPayload_main` as shown below:
```C++
extern "C" int AVmPayload_main() {
printf("Hello Microdroid!\n");
}
```
Then build it as a shared library:
```
cc_library_shared {
name: "MyMicrodroidPayload",
srcs: ["**/*.cpp"],
sdk_version: "current",
}
```
Embed the shared library file in an APK:
```
android_app {
name: "MyApp",
srcs: ["**/*.java"],
jni_libs: ["MyMicrodroidPayload"],
use_embedded_native_libs: true,
sdk_version: "current",
}
```
Finally, you build the APK.
```sh
TARGET_BUILD_APPS=MyApp m apps_only dist
```
## Running the VM payload on microdroid
First of all, install the APK to the target device.
```sh
adb install out/dist/MyApp.apk
```
There are two ways start a VM and run the payload in it.
* By manually invoking the `vm` tool via `adb shell`.
* Calling APIs programmatically in the Java app.
### Using `vm` tool
Execute the following commands to launch a VM. The VM will boot to microdroid
and then automatically execute your payload (the shared library
`MyMicrodroidPayload.so`).
```sh
TEST_ROOT=/data/local/tmp/virt
adb shell /apex/com.android.virt/bin/vm run-app \
--log $TEST_ROOT/log.txt \
--console $TEST_ROOT/console.txt \
PATH_TO_YOUR_APP \
$TEST_ROOT/MyApp.apk.idsig \
$TEST_ROOT/instance.img \
--instance-id-file $TEST_ROOT/instance_id \
--payload-binary-name MyMicrodroidPayload.so
```
`ALL_CAP`s below are placeholders. They need to be replaced with correct
values:
* `PACKAGE_NAME_OF_YOUR_APP`: package name of your app (e.g. `com.acme.app`).
* `PATH_TO_YOUR_APP`: path to the installed APK on the device. Can be obtained
via the following command.
```sh
adb shell pm path PACKAGE_NAME_OF_YOUR_APP
```
It shall report a cryptic path similar to `/data/app/~~OgZq==/com.acme.app-HudMahQ==/base.apk`.
The console output from the VM is stored to `$TEST_ROOT/console.txt` and logcat
is stored to `$TEST_ROOT/log.txt` file for debugging purpose. If you omit
`--log` or `--console` option, the console output will be emitted to the
current console and the logcat logs are sent to the main logcat in Android.
Stopping the VM can be done by pressing `Ctrl+C`.
### Using the APIs
Use the [Android Virtualization Framework Java
APIs](https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/java/framework/README.md)
in your app to create a microdroid VM and run payload in it. The APIs are currently
@SystemApi, and only available to preinstalled apps.
If you are looking for an example usage of the APIs, you may refer to the [demo
app](https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/demo/).
## Running Microdroid with vendor image
With using `vm` tool, execute the following commands to launch a VM with vendor
partition.
```sh
adb shell /apex/com.android.virt/bin/vm run-microdroid \
--vendor $VENDOR_IMAGE
```
### Verification of vendor image
Since vendor image of Microdroid is not part of `com.android.virt` APEX, the
verification process of vendor partition is different from others.
Vendor image uses its hashtree digest for the verifying its data, generated
by `add_hashtree_footer` in `avbtool`. The value could be seen with following
command:
```sh
avbtool info_image --image $VENDOR_IMAGE
```
Fixed path in VM for vendor hashtree digest is written in [fstab.microdroid].
During first stage init of VM, [dm-verity] is set up based on vendor hashtree
digest by reading [fstab.microdroid].
For non-pVM, virtualizationmanager creates [DTBO] containing vendor hashtree
digest, and passes to the VM via crosvm option. The vendor hashtree digest is
obtained by virtualizationmanager from the host Android DT under
`/avf/reference/`, which may be populated by the [bootloader].
For pVM, VM reference DT included in [pvmfw config data] is additionally used
for validating vendor hashtree digest. [Bootloader][bootloader] should append
vendor hashtree digest into VM reference DT based on [fstab.microdroid]. Vendor
hashtree digest could be appended as property into descriptors in host Android's
vendor image by [Makefile] when Microdroid vendor image module is defined, so
that a [bootloader] can extract the value and populate into VM reference DT.
[fstab.microdroid]: fstab.microdroid
[dm-verity]: https://source.android.com/docs/security/features/verifiedboot/dm-verity
[DTBO]: https://android.googlesource.com/platform/external/dtc/+/refs/heads/main/Documentation/dt-object-internal.txt
[pvmfw config data]: ../pvmfw/README.md#configuration-data-format
[bootloader]: https://source.android.com/docs/core/architecture/bootloader
[Makefile]: https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile
## Debugging Microdroid
Refer to [Debugging protected VMs](../docs/debug/README.md).