Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 1 | # Getting started with Android Virtualization Framework |
David Brazdil | dd56510 | 2020-10-23 16:33:30 +0000 | [diff] [blame] | 2 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 3 | ## Step 1: Prepare a device |
David Brazdil | dd56510 | 2020-10-23 16:33:30 +0000 | [diff] [blame] | 4 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 5 | We support the following devices: |
David Brazdil | dd56510 | 2020-10-23 16:33:30 +0000 | [diff] [blame] | 6 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 7 | * aosp\_panther (Pixel 7) |
| 8 | * aosp\_cheetah (Pixel 7 Pro) |
| 9 | * aosp\_oriole (Pixel 6) |
| 10 | * aosp\_raven (Pixel 6 Pro) |
| 11 | * aosp\_felix (Pixel Fold) |
| 12 | * aosp\_tangopro (Pixel Tablet) |
| 13 | * aosp\_cf\_x86\_64\_phone (Cuttlefish a.k.a. Cloud Android). Follow [this |
| 14 | instruction](https://source.android.com/docs/setup/create/cuttlefish-use) to |
| 15 | use. |
David Brazdil | dd56510 | 2020-10-23 16:33:30 +0000 | [diff] [blame] | 16 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 17 | ### Note on Pixel 6 and 6 Pro |
| 18 | AVF is shipped in Pixel 6 and 6 Pro, but isn't enabled by default. To enable |
| 19 | it, follow the instructions below: |
| 20 | |
| 21 | 1. If the device is running Android 13 or earlier, upgrade to Android 14. |
| 22 | |
| 23 | 1. Once upgraded to Android 14, execute the following command to enable pKVM. |
| 24 | ```shell |
| 25 | adb reboot bootloader |
| 26 | fastboot flashing unlock |
| 27 | fastboot oem pkvm enable |
| 28 | fastboot reboot |
| 29 | ``` |
| 30 | ### Note on Cuttlefish |
| 31 | Cuttlefish does not support protected VMs. Only non-protected VMs are |
| 32 | supported. |
| 33 | |
| 34 | ## Step 2: Build Android image |
| 35 | |
| 36 | This step is optional unless you want to build AVF by yourself or try the |
| 37 | in-development version of AVF. |
| 38 | |
| 39 | AVF is implemented as an APEX named `com.android.virt`. However, in order for |
| 40 | you to install it to your device (be it Pixel or Cuttlefish), you first need to |
| 41 | re-build the entire Android from AOSP. This is because the official Android |
| 42 | build you have in your device is release-key signed and therefore you can't |
| 43 | install your custom-built AVF APEX to it - because it is test-key signed. |
| 44 | |
| 45 | ### Pixel |
| 46 | |
| 47 | 1. [Download](https://source.android.com/docs/setup/download/downloading) |
| 48 | source code from AOSP. Use the `main` branch. |
| 49 | |
| 50 | 1. [Download](https://developers.google.com/android/blobs-preview) the preview |
| 51 | vendor blob that matches your device. |
| 52 | |
| 53 | 1. [Build](https://source.android.com/docs/setup/build/building) the `aosp_` |
| 54 | variant of your device. For example, if your device is Pixel 7 (`panther`), |
| 55 | build `aosp_panther`. |
| 56 | |
| 57 | 1. [Flash](https://source.android.com/docs/setup/build/running) the built |
| 58 | images to the device. |
| 59 | |
Jiyong Park | 60c8aef | 2022-06-10 15:51:22 +0900 | [diff] [blame] | 60 | |
| 61 | ### Cuttlefish |
Jiyong Park | 10b354a | 2021-11-17 17:46:53 +0900 | [diff] [blame] | 62 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 63 | 1. [Download](https://source.android.com/docs/setup/download/downloading) |
| 64 | source code from AOSP. Use the `main` branch. |
| 65 | |
| 66 | 1. Build Cuttlefish: |
| 67 | ```shell |
| 68 | source build/envsetup.sh |
| 69 | lunch aosp_cf_x86_64_phone-userdebug |
| 70 | m |
| 71 | ``` |
| 72 | |
| 73 | 1. Run Cuttlefish: |
| 74 | ```shell |
| 75 | cvd start |
| 76 | ``` |
| 77 | |
| 78 | ## Step 3: Build AVF |
| 79 | |
| 80 | Then you can repeat building and installing AVF to the device as follows: |
| 81 | |
| 82 | 1. Build the AVF APEX. |
| 83 | ```sh |
| 84 | banchan com.android.virt aosp_arm64 |
| 85 | UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m apps_only dist |
| 86 | ``` |
| 87 | Replace `aosp_arm64` with `aosp_x86_64` if you are building for Cuttlefish. |
| 88 | |
| 89 | 1. Install the AVF APEX to the device. |
| 90 | ```sh |
| 91 | adb install out/dist/com.android.virt.apex |
| 92 | adb reboot; adb wait-for-device |
| 93 | ``` |
| 94 | |
| 95 | ## Step 4: Run a Microdroid VM |
| 96 | |
Jiyong Park | 8107110 | 2024-07-22 12:48:17 +0900 | [diff] [blame] | 97 | [Microdroid](../../build/microdroid/README.md) is a lightweight version of Android |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 98 | that is intended to run on pVM. You can run a Microdroid-based VM with an empty |
| 99 | payload using the following command: |
Jiyong Park | 10b354a | 2021-11-17 17:46:53 +0900 | [diff] [blame] | 100 | |
| 101 | ```shell |
Andrew Walbran | 5fa9290 | 2023-08-22 17:09:12 +0100 | [diff] [blame] | 102 | packages/modules/Virtualization/vm/vm_shell.sh start-microdroid --auto-connect -- --protected |
Jiyong Park | 10b354a | 2021-11-17 17:46:53 +0900 | [diff] [blame] | 103 | ``` |
| 104 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 105 | You will see the log messages like the below. |
Jiyong Park | 10b354a | 2021-11-17 17:46:53 +0900 | [diff] [blame] | 106 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 107 | ``` |
| 108 | found path /apex/com.android.virt/app/EmptyPayloadAppGoogle@MASTER/EmptyPayloadAppGoogle.apk |
| 109 | creating work dir /data/local/tmp/microdroid/7CI6QtktSluD3OZgv |
| 110 | apk.idsig path: /data/local/tmp/microdroid/7CI6QtktSluD3OZgv/apk.idsig |
| 111 | instance.img path: /data/local/tmp/microdroid/7CI6QtktSluD3OZgv/instance.img |
| 112 | Created VM from "/apex/com.android.virt/app/EmptyPayloadAppGoogle@MASTER/EmptyPayloadAppGoogle.apk"!PayloadConfig(VirtualMachinePayloadConfig { payloadBinaryName: "MicrodroidEmptyPayloadJniLib.so" }) with CID 2052, state is STARTING. |
| 113 | [2023-07-07T14:50:43.420766770+09:00 INFO crosvm] crosvm started. |
| 114 | [2023-07-07T14:50:43.422545090+09:00 INFO crosvm] CLI arguments parsed. |
| 115 | [2023-07-07T14:50:43.440984015+09:00 INFO crosvm::crosvm::sys::unix::device_helpers] Trying to attach block device: /proc/self/fd/49 |
| 116 | [2023-07-07T14:50:43.441730922+09:00 INFO crosvm::crosvm::sys::unix::device_helpers] Trying to attach block device: /proc/self/fd/54 |
| 117 | [2023-07-07T14:50:43.462055141+09:00 INFO crosvm::crosvm::sys::unix::device_helpers] Trying to attach block device: /proc/self/fd/63 |
| 118 | [WARN] Config entry DebugPolicy uses non-zero offset with zero size |
| 119 | [WARN] Config entry DebugPolicy uses non-zero offset with zero size |
| 120 | [INFO] pVM firmware |
| 121 | avb_slot_verify.c:443: ERROR: initrd_normal: Hash of data does not match digest in descriptor. |
| 122 | [INFO] device features: SEG_MAX | RO | BLK_SIZE | RING_EVENT_IDX | VERSION_1 | ACCESS_PLATFORM |
| 123 | [INFO] config: 0x201a000 |
| 124 | [INFO] found a block device of size 50816KB |
| 125 | [INFO] device features: SEG_MAX | BLK_SIZE | FLUSH | DISCARD | WRITE_ZEROES | RING_EVENT_IDX | VERSION_1 | ACCESS_PLATFORM |
| 126 | [INFO] config: 0x2022000 |
| 127 | [INFO] found a block device of size 10304KB |
| 128 | [INFO] No debug policy found. |
| 129 | [INFO] Starting payload... |
| 130 | <omitted> |
| 131 | 07-07 05:52:01.322 69 69 I vm_payload: vm_payload: Notified host payload ready successfully |
| 132 | 07-07 05:52:01.364 70 70 I adbd : persist.adb.watchdog set to '' |
| 133 | 07-07 05:52:01.364 70 70 I adbd : persist.sys.test_harness set to '' |
| 134 | 07-07 05:52:01.365 70 70 I adbd : adb watchdog timeout set to 600 seconds |
| 135 | 07-07 05:52:01.366 70 70 I adbd : Setup mdns on port= 5555 |
| 136 | 07-07 05:52:01.366 70 70 I adbd : adbd listening on vsock:5555 |
| 137 | 07-07 05:52:01.366 70 70 I adbd : adbd started |
| 138 | # |
Jiyong Park | 10b354a | 2021-11-17 17:46:53 +0900 | [diff] [blame] | 139 | ``` |
| 140 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 141 | The `--auto-connect` option provides you an adb-shell connection to the VM. The |
| 142 | shell promot (`#`) at the end of the log is for that. |
Jiyong Park | 60c8aef | 2022-06-10 15:51:22 +0900 | [diff] [blame] | 143 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 144 | ## Step 5: Run tests |
Jiyong Park | 60c8aef | 2022-06-10 15:51:22 +0900 | [diff] [blame] | 145 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 146 | There are various tests that spawn guest VMs and check different aspects of the |
| 147 | architecture. They all can run via `atest`. |
Andrew Walbran | 0479a65 | 2021-04-12 11:17:13 +0000 | [diff] [blame] | 148 | |
| 149 | ```shell |
Kalesh Singh | b507098 | 2021-12-14 23:21:39 -0800 | [diff] [blame] | 150 | atest MicrodroidHostTestCases |
| 151 | atest MicrodroidTestApp |
David Brazdil | dd56510 | 2020-10-23 16:33:30 +0000 | [diff] [blame] | 152 | ``` |
| 153 | |
Jiyong Park | 616b17c | 2023-07-07 15:21:30 +0900 | [diff] [blame] | 154 | If you run into problems, inspect the logs produced by `atest`. Their location |
| 155 | is printed at the end. The `host_log_*.zip` file should contain the output of |
| 156 | individual commands as well as VM logs. |