doc: major refactoring of the getting started doc

These are the summary of the changes:

* Clarify each step
* Move advanced topic (like using custom VM, or customizing pvmfw) out
  of the getting started doc
* Use the vm_shell script (instead of the vm tool which doesn't give you
  the adb-shell connection out of the box) to start a microdroid VM
* Show the expected logs so that users can check if they are doing well
* Add instructions to build Pixels from AOSP (including how to download
  preview vendor blobs)
* Use the existing public links wherever possible (e.g. how to download
  & flash)
* Start cuttlefish using `cvd start` instead of the old `acloud`
  command which is being deprecated.

Bug: N/A
Test: N/A
Change-Id: Ifc92a85b57c6ab0118082cea7b27bbd90b92c460
diff --git a/README.md b/README.md
index eb47b16..eaa2579 100644
--- a/README.md
+++ b/README.md
@@ -26,3 +26,4 @@
 * [Building and running a demo app in Java](demo/README.md)
 * [Building and running a demo app in C++](demo_native/README.md)
 * [Debugging](docs/debug)
+* [Using custom VM](docs/custom_vm.md)
diff --git a/docs/custom_vm.md b/docs/custom_vm.md
new file mode 100644
index 0000000..270ea36
--- /dev/null
+++ b/docs/custom_vm.md
@@ -0,0 +1,23 @@
+# Custom VM
+
+You can spawn your own custom VMs by passing a JSON config file to the
+VirtualizationService via the `vm` tool on a rooted AVF-enabled device. If your
+device is attached over ADB, you can run:
+
+```shell
+cat > vm_config.json <<EOF
+{
+  "kernel": "/data/local/tmp/kernel",
+  "initrd": "/data/local/tmp/ramdisk",
+  "params": "rdinit=/bin/init"
+}
+EOF
+adb root
+adb push <kernel> /data/local/tmp/kernel
+adb push <ramdisk> /data/local/tmp/ramdisk
+adb push vm_config.json /data/local/tmp/vm_config.json
+adb shell "/apex/com.android.virt/bin/vm run /data/local/tmp/vm_config.json"
+```
+
+The `vm` command also has other subcommands for debugging; run
+`/apex/com.android.virt/bin/vm help` for details.
diff --git a/docs/getting_started.md b/docs/getting_started.md
index 9dcd4fa..d970c12 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -1,126 +1,156 @@
-# Getting started with Protected Virtual Machines
+# Getting started with Android Virtualization Framework
 
-## Prepare a device
+## Step 1: Prepare a device
 
-First you will need a device that is capable of running virtual machines. On arm64, this means a
-device which boots the kernel in EL2 and the kernel was built with KVM enabled. Unfortunately at the
-moment, we don't have an arm64 device in AOSP which does that. Instead, use cuttlefish which
-provides the same functionalities except that the virtual machines are not protected from the host
-(i.e. Android). This however should be enough for functional testing.
+We support the following devices:
 
-We support the following device:
+* aosp\_panther (Pixel 7)
+* aosp\_cheetah (Pixel 7 Pro)
+* aosp\_oriole (Pixel 6)
+* aosp\_raven (Pixel 6 Pro)
+* aosp\_felix (Pixel Fold)
+* aosp\_tangopro (Pixel Tablet)
+* aosp\_cf\_x86\_64\_phone (Cuttlefish a.k.a. Cloud Android). Follow [this
+  instruction](https://source.android.com/docs/setup/create/cuttlefish-use) to
+  use.
 
-* aosp_cf_x86_64_phone (Cuttlefish a.k.a. Cloud Android)
-* oriole/raven (Pixel 6, and 6 Pro)
-* panther/cheetah (Pixel 7, and 7 Pro)
+### Note on Pixel 6 and 6 Pro
+AVF is shipped in Pixel 6 and 6 Pro, but isn't enabled by default. To enable
+it, follow the instructions below:
+
+1. If the device is running Android 13 or earlier, upgrade to Android 14.
+
+1. Once upgraded to Android 14, execute the following command to enable pKVM.
+   ```shell
+   adb reboot bootloader
+   fastboot flashing unlock
+   fastboot oem pkvm enable
+   fastboot reboot
+   ```
+### Note on Cuttlefish
+Cuttlefish does not support protected VMs. Only non-protected VMs are
+supported.
+
+## Step 2: Build Android image
+
+This step is optional unless you want to build AVF by yourself or try the
+in-development version of AVF.
+
+AVF is implemented as an APEX named `com.android.virt`. However, in order for
+you to install it to your device (be it Pixel or Cuttlefish), you first need to
+re-build the entire Android from AOSP. This is because the official Android
+build you have in your device is release-key signed and therefore you can't
+install your custom-built AVF APEX to it - because it is test-key signed.
+
+### Pixel
+
+1. [Download](https://source.android.com/docs/setup/download/downloading)
+   source code from AOSP. Use the `main` branch.
+
+1. [Download](https://developers.google.com/android/blobs-preview) the preview
+   vendor blob that matches your device.
+
+1. [Build](https://source.android.com/docs/setup/build/building) the `aosp_`
+   variant of your device. For example, if your device is Pixel 7 (`panther`),
+   build `aosp_panther`.
+
+1. [Flash](https://source.android.com/docs/setup/build/running) the built
+   images to the device.
+
 
 ### Cuttlefish
 
-Building Cuttlefish
+1. [Download](https://source.android.com/docs/setup/download/downloading)
+   source code from AOSP. Use the `main` branch.
+
+1. Build Cuttlefish:
+   ```shell
+   source build/envsetup.sh
+   lunch aosp_cf_x86_64_phone-userdebug
+   m
+   ```
+
+1. Run Cuttlefish:
+   ```shell
+   cvd start
+   ```
+
+## Step 3: Build AVF
+
+Then you can repeat building and installing AVF to the device as follows:
+
+1. Build the AVF APEX.
+   ```sh
+   banchan com.android.virt aosp_arm64
+   UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m apps_only dist
+   ```
+   Replace `aosp_arm64` with `aosp_x86_64` if you are building for Cuttlefish.
+
+1. Install the AVF APEX to the device.
+   ```sh
+   adb install out/dist/com.android.virt.apex
+   adb reboot; adb wait-for-device
+   ```
+
+## Step 4: Run a Microdroid VM
+
+[Microdroid](../../microdroid/README.md) is a lightweight version of Android
+that is intended to run on pVM. You can run a Microdroid-based VM with an empty
+payload using the following command:
 
 ```shell
-source build/envsetup.sh
-lunch aosp_cf_x86_64_phone-userdebug
-m
+package/modules/Virtualization/vm/vm_shell.sh start-microdroid --auto-connect -- --protected
 ```
 
-Run Cuttlefish locally by
+You will see the log messages like the below.
 
-```shell
-acloud create --local-instance --local-image
+```
+found path /apex/com.android.virt/app/EmptyPayloadAppGoogle@MASTER/EmptyPayloadAppGoogle.apk
+creating work dir /data/local/tmp/microdroid/7CI6QtktSluD3OZgv
+apk.idsig path: /data/local/tmp/microdroid/7CI6QtktSluD3OZgv/apk.idsig
+instance.img path: /data/local/tmp/microdroid/7CI6QtktSluD3OZgv/instance.img
+Created VM from "/apex/com.android.virt/app/EmptyPayloadAppGoogle@MASTER/EmptyPayloadAppGoogle.apk"!PayloadConfig(VirtualMachinePayloadConfig { payloadBinaryName: "MicrodroidEmptyPayloadJniLib.so" }) with CID 2052, state is STARTING.
+[2023-07-07T14:50:43.420766770+09:00 INFO  crosvm] crosvm started.
+[2023-07-07T14:50:43.422545090+09:00 INFO  crosvm] CLI arguments parsed.
+[2023-07-07T14:50:43.440984015+09:00 INFO  crosvm::crosvm::sys::unix::device_helpers] Trying to attach block device: /proc/self/fd/49
+[2023-07-07T14:50:43.441730922+09:00 INFO  crosvm::crosvm::sys::unix::device_helpers] Trying to attach block device: /proc/self/fd/54
+[2023-07-07T14:50:43.462055141+09:00 INFO  crosvm::crosvm::sys::unix::device_helpers] Trying to attach block device: /proc/self/fd/63
+[WARN] Config entry DebugPolicy uses non-zero offset with zero size
+[WARN] Config entry DebugPolicy uses non-zero offset with zero size
+[INFO] pVM firmware
+avb_slot_verify.c:443: ERROR: initrd_normal: Hash of data does not match digest in descriptor.
+[INFO] device features: SEG_MAX | RO | BLK_SIZE | RING_EVENT_IDX | VERSION_1 | ACCESS_PLATFORM
+[INFO] config: 0x201a000
+[INFO] found a block device of size 50816KB
+[INFO] device features: SEG_MAX | BLK_SIZE | FLUSH | DISCARD | WRITE_ZEROES | RING_EVENT_IDX | VERSION_1 | ACCESS_PLATFORM
+[INFO] config: 0x2022000
+[INFO] found a block device of size 10304KB
+[INFO] No debug policy found.
+[INFO] Starting payload...
+<omitted>
+07-07 05:52:01.322    69    69 I vm_payload: vm_payload: Notified host payload ready successfully
+07-07 05:52:01.364    70    70 I adbd    : persist.adb.watchdog set to ''
+07-07 05:52:01.364    70    70 I adbd    : persist.sys.test_harness set to ''
+07-07 05:52:01.365    70    70 I adbd    : adb watchdog timeout set to 600 seconds
+07-07 05:52:01.366    70    70 I adbd    : Setup mdns on port= 5555
+07-07 05:52:01.366    70    70 I adbd    : adbd listening on vsock:5555
+07-07 05:52:01.366    70    70 I adbd    : adbd started
+#
 ```
 
-### Google Pixel phones
+The `--auto-connect` option provides you an adb-shell connection to the VM. The
+shell promot (`#`) at the end of the log is for that.
 
-If the device is running Android 13 or earlier, join the [Android Beta
-Program](https://developer.android.com/about/versions/14/get#on_pixel) to upgrade to Android 14
-Beta.
+## Step 5: Run tests
 
-Once upgraded to Android 14, and if you are using Pixel 6 or 6 Pro, execute the following command to
-enable pKVM. You don't need to do this for Pixel 7 and 7 Pro.
-
-```shell
-adb reboot bootloader
-fastboot flashing unlock
-fastboot oem pkvm enable
-fastboot reboot
-```
-
-## Running demo app
-
-The instruction is [here](../../demo/README.md).
-
-## Running tests
-
-There are various tests that spawn guest VMs and check different aspects of the architecture. They
-all can run via `atest`.
+There are various tests that spawn guest VMs and check different aspects of the
+architecture. They all can run via `atest`.
 
 ```shell
 atest MicrodroidHostTestCases
 atest MicrodroidTestApp
 ```
 
-If you run into problems, inspect the logs produced by `atest`. Their location is printed at the
-end. The `host_log_*.zip` file should contain the output of individual commands as well as VM logs.
-
-## Spawning your own VMs with custom kernel
-
-You can spawn your own VMs by passing a JSON config file to the VirtualizationService via the `vm`
-tool on a rooted KVM-enabled device. If your device is attached over ADB, you can run:
-
-```shell
-cat > vm_config.json
-{
-  "kernel": "/data/local/tmp/kernel",
-  "initrd": "/data/local/tmp/ramdisk",
-  "params": "rdinit=/bin/init"
-}
-adb root
-adb push <kernel> /data/local/tmp/kernel
-adb push <ramdisk> /data/local/tmp/ramdisk
-adb push vm_config.json /data/local/tmp/vm_config.json
-adb shell "start virtualizationservice"
-adb shell "/apex/com.android.virt/bin/vm run /data/local/tmp/vm_config.json"
-```
-
-The `vm` command also has other subcommands for debugging; run `/apex/com.android.virt/bin/vm help`
-for details.
-
-## Spawning your own VMs with custom pvmfw
-
-Set system property `hypervisor.pvmfw.path` to custom `pvmfw` on the device before using `vm` tool.
-`virtualizationservice` will pass the specified `pvmfw` to `crosvm` for protected VMs.
-
-```shell
-adb push pvmfw.img /data/local/tmp/pvmfw.img
-adb root  # required for setprop
-adb shell setprop hypervisor.pvmfw.path /data/local/tmp/pvmfw.img
-```
-
-## Spawning your own VMs with Microdroid
-
-[Microdroid](../../microdroid/README.md) is a lightweight version of Android that is intended to run
-on pVM. You can run a Microdroid with empty payload using the following command:
-
-```shell
-adb shell /apex/com.android.virt/bin/vm run-microdroid
-```
-
-which spawns a "debuggable" VM by default to allow access to guest kernel logs.
-To run a production non-debuggable VM, pass `--debug none`.
-
-## Building and updating CrosVM and VirtualizationService {#building-and-updating}
-
-You can update CrosVM and the VirtualizationService by updating the `com.android.virt` APEX instead
-of rebuilding the entire image.
-
-```shell
-banchan com.android.virt aosp_arm64   // or aosp_x86_64 if the device is cuttlefish
-UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true m apps_only dist
-adb install out/dist/com.android.virt.apex
-adb reboot
-```
-
-## Building and updating kernel inside Microdroid
-
-The instruction is [here](../../microdroid/kernel/README.md).
+If you run into problems, inspect the logs produced by `atest`. Their location
+is printed at the end. The `host_log_*.zip` file should contain the output of
+individual commands as well as VM logs.
diff --git a/pvmfw/README.md b/pvmfw/README.md
index 4e93648..950067e 100644
--- a/pvmfw/README.md
+++ b/pvmfw/README.md
@@ -433,3 +433,25 @@
 kernel][soong-udroid]).
 
 [soong-udroid]: https://cs.android.com/android/platform/superproject/+/master:packages/modules/Virtualization/microdroid/Android.bp;l=427;drc=ca0049be4d84897b8c9956924cfae506773103eb
+
+## Development
+
+For faster iteration, you can build pvmfw, adb-push it to the device, and use
+it directly for a new pVM, without having to flash it to the physical
+partition. To do that, set the system property `hypervisor.pvmfw.path` to point
+to the pvmfw image you pushed as shown below:
+
+```shell
+m pvmfw_img
+adb push out/target/product/generic_arm64/system/etc/pvmfw.img /data/local/tmp/pvmfw.img
+adb root
+adb shell setprop hypervisor.pvmfw.path /data/local/tmp/pvmfw.img
+```
+
+Then run a protected VM, for example:
+
+```shell
+adb shell /apex/com.android.virt/bin/vm run-microdroid --protected
+```
+
+Note: `adb root` is required to set the system property.