README.md
1# Microdroid
2
3Microdroid is a (very) lightweight version of Android that is intended to run on
4on-device virtual machines. It is built from the same source code as the regular
5Android, but it is much smaller; no system server, no HALs, no GUI, etc. It is
6intended to host headless & native workloads only.
7
8## Prerequisites
9
10Any 64-bit target (either x86\_64 or arm64) is supported. 32-bit target is not
11supported.
12
13The only remaining requirement is that `com.android.virt` APEX has to be
14pre-installed. To do this, add the following line in your product makefile.
15
16```make
17$(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)
18```
19
20Build the target product after adding the line, and flash it. This step needs
21to be done only once for the target.
22
23If you are using Pixel 6 and beyond or Cuttlefish (`aosp_cf_x86_64_phone`)
24adding above line is not necessary as it's already done.
25
26## Building and installing microdroid
27
28Microdroid is part of the `com.android.virt` APEX. To build it and install to
29the device:
30
31```sh
32banchan com.android.virt aosp_arm64
33UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m apps_only dist
34adb install out/dist/com.android.virt.apex
35adb reboot
36```
37
38If your target is x86\_64 (e.g. `aosp_cf_x86_64_phone`), replace `aosp_arm64`
39with `aosp_x86_64`.
40
41## Building an app
42
43A [vm
44payload](https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/vm_payload/)
45is a shared library file that gets executed in microdroid. It is packaged as
46part of an Android application. The library should have an entry point
47`AVmPayload_main` as shown below:
48
49```C++
50extern "C" int AVmPayload_main() {
51 printf("Hello Microdroid!\n");
52}
53```
54
55Then build it as a shared library:
56
57```
58cc_library_shared {
59 name: "MyMicrodroidPayload",
60 srcs: ["**/*.cpp"],
61 sdk_version: "current",
62}
63```
64
65Embed the shared library file in an APK:
66
67```
68android_app {
69 name: "MyApp",
70 srcs: ["**/*.java"],
71 jni_libs: ["MyMicrodroidPayload"],
72 use_embedded_native_libs: true,
73 sdk_version: "current",
74}
75```
76
77Finally, you build the APK.
78
79```sh
80TARGET_BUILD_APPS=MyApp m apps_only dist
81```
82
83## Running the VM payload on microdroid
84
85First of all, install the APK to the target device.
86
87```sh
88adb install out/dist/MyApp.apk
89```
90
91There are two ways start a VM and run the payload in it.
92
93* By manually invoking the `vm` tool via `adb shell`.
94* Calling APIs programmatically in the Java app.
95
96### Using `vm` tool
97
98Execute the following commands to launch a VM. The VM will boot to microdroid
99and then automatically execute your payload (the shared library
100`MyMicrodroidPayload.so`).
101
102```sh
103TEST_ROOT=/data/local/tmp/virt
104adb shell /apex/com.android.virt/bin/vm run-app \
105--log $TEST_ROOT/log.txt \
106--console $TEST_ROOT/console.txt \
107PATH_TO_YOUR_APP \
108$TEST_ROOT/MyApp.apk.idsig \
109$TEST_ROOT/instance.img \
110--instance-id-file $TEST_ROOT/instance_id \
111--payload-binary-name MyMicrodroidPayload.so
112```
113
114`ALL_CAP`s below are placeholders. They need to be replaced with correct
115values:
116
117* `PACKAGE_NAME_OF_YOUR_APP`: package name of your app (e.g. `com.acme.app`).
118* `PATH_TO_YOUR_APP`: path to the installed APK on the device. Can be obtained
119 via the following command.
120 ```sh
121 adb shell pm path PACKAGE_NAME_OF_YOUR_APP
122 ```
123 It shall report a cryptic path similar to `/data/app/~~OgZq==/com.acme.app-HudMahQ==/base.apk`.
124
125The console output from the VM is stored to `$TEST_ROOT/console.txt` and logcat
126is stored to `$TEST_ROOT/log.txt` file for debugging purpose. If you omit
127`--log` or `--console` option, the console output will be emitted to the
128current console and the logcat logs are sent to the main logcat in Android.
129
130Stopping the VM can be done by pressing `Ctrl+C`.
131
132### Using the APIs
133
134Use the [Android Virtualization Framework Java
135APIs](https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/java/framework/README.md)
136in your app to create a microdroid VM and run payload in it. The APIs are currently
137@SystemApi, and only available to preinstalled apps.
138
139If you are looking for an example usage of the APIs, you may refer to the [demo
140app](https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/demo/).
141
142
143## Running Microdroid with vendor image
144
145With using `vm` tool, execute the following commands to launch a VM with vendor
146partition.
147
148```sh
149adb shell /apex/com.android.virt/bin/vm run-microdroid \
150--vendor $VENDOR_IMAGE
151```
152
153### Verification of vendor image
154
155Since vendor image of Microdroid is not part of `com.android.virt` APEX, the
156verification process of vendor partition is different from others.
157
158Vendor image uses its hashtree digest for the verifying its data, generated
159by `add_hashtree_footer` in `avbtool`. The value could be seen with following
160command:
161
162```sh
163avbtool info_image --image $VENDOR_IMAGE
164```
165
166Fixed path in VM for vendor hashtree digest is written in [fstab.microdroid].
167During first stage init of VM, [dm-verity] is set up based on vendor hashtree
168digest by reading [fstab.microdroid].
169
170For non-pVM, virtualizationmanager creates [DTBO] containing vendor hashtree
171digest, and passes to the VM via crosvm option. The vendor hashtree digest is
172obtained by virtualizationmanager from the host Android DT under
173`/avf/reference/`, which may be populated by the [bootloader].
174
175For pVM, VM reference DT included in [pvmfw config data] is additionally used
176for validating vendor hashtree digest. [Bootloader][bootloader] should append
177vendor hashtree digest into VM reference DT based on [fstab.microdroid]. Vendor
178hashtree digest could be appended as property into descriptors in host Android's
179vendor image by [Makefile] when Microdroid vendor image module is defined, so
180that a [bootloader] can extract the value and populate into VM reference DT.
181
182[fstab.microdroid]: fstab.microdroid
183[dm-verity]: https://source.android.com/docs/security/features/verifiedboot/dm-verity
184[DTBO]: https://android.googlesource.com/platform/external/dtc/+/refs/heads/main/Documentation/dt-object-internal.txt
185[pvmfw config data]: ../pvmfw/README.md#configuration-data-format
186[bootloader]: https://source.android.com/docs/core/architecture/bootloader
187[Makefile]: https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile
188
189## Debugging Microdroid
190
191Refer to [Debugging protected VMs](../docs/debug/README.md).
192