Merge "Add a README for vm_payload"
diff --git a/vm_payload/README.md b/vm_payload/README.md
new file mode 100644
index 0000000..6ce6770
--- /dev/null
+++ b/vm_payload/README.md
@@ -0,0 +1,70 @@
+# VM Payload API
+
+This directory contains the definition of the VM Payload API. This is a native
+API, exposed as a set of C functions, available to payload code running inside a
+[Microdroid](../microdroid/README.md) VM.
+
+Note that only native code is supported in Microdroid, so no Java APIs are
+available in the VM, and only 64 bit code is supported.
+
+To create a VM and run the payload from Android, see
+[android.system.virtualmachine.VirtualMachineManager](../javalib/src/android/system/virtualmachine/VirtualMachineManager.java).
+
+## Entry point
+
+The payload should be packaged as one (or more) .so files inside the app's APK -
+under the `lib/<ABI>` directory, like other JNI code.
+
+The primary .so, which is specified as part of the VM configuration via
+[VirtualMachineConfig.Builder#setPayloadBinaryPath](../javalib/src/android/system/virtualmachine/VirtualMachineConfig.java),
+must define the entry point for the payload.
+
+This entry point is a C function called `AVmPayload_main()`, as declared in
+[vm_main.h](include/vm_main.h). (In C++ this must be defined as `extern "C"`.)
+
+## API header
+
+The functions available to the payload once it starts are declared in
+[vm_payload.h](include/vm_payload.h).
+
+### Linking
+
+In the Android build system, the payload binary should be built with
+`libvm_payload#current` specified as one of the `shared_libs`; this links
+against a stub `libvm_payload.so`, where the dependencies will be satisfied at
+runtime from the real `libvm_payload.so` hosted within the Microdroid VM.
+
+See `MicrodroidTestNativeLib` in the [test APK](../tests/testapk/Android.bp) for
+an example.
+
+In other build systems a similar stub `libvm_payload.so` can be built using
+[stub.c](stub/stub.c).
+
+## Available NDK APIs
+
+In addition to the VM Payload APIs, a small subset of the [Android
+NDK](https://developer.android.com/ndk) can be used by the payload.
+
+This subset consists of:
+- The [standard C library](https://developer.android.com/ndk/guides/stable_apis#c_library).
+- The [Logging APIs](https://developer.android.com/ndk/guides/stable_apis#logging).
+- The [NdkBinder
+  API](https://developer.android.com/ndk/reference/group/ndk-binder). However
+  note that the payload can only host a binder server via
+  `AVmPayload_runVsockRpcServer`, defined in
+  [vm_payload.h](include/vm_payload.h), rather than
+  `AServiceManager_addService`, and cannot connect to any binder server. Passing
+  file descriptors to and from the VM is not supported.
+
+## C++
+
+C++ can be used, but you will need to include the C++ runtime in your APK along
+with your payload, either statically linked (if
+[appropriate](https://developer.android.com/ndk/guides/cpp-support#sr) or as a
+separate .so.
+
+The same is true for other languages such as Rust.
+
+See [AIDL
+backends](https://source.android.com/docs/core/architecture/aidl/aidl-backends)
+for information on using AIDL with the NDK Binder from C++.
diff --git a/vm_payload/include/vm_main.h b/vm_payload/include/vm_main.h
index e351174..5158b43 100644
--- a/vm_payload/include/vm_main.h
+++ b/vm_payload/include/vm_main.h
@@ -23,5 +23,17 @@
 }
 #else
 typedef int AVmPayload_main_t(void);
+
+/**
+ * Entry point for the VM payload. This function must be implemented by the
+ * payload binary, and is called by Microdroid to start the payload inside the
+ * VM.
+ *
+ * When the function returns the VM will be shut down.  If the host app has set
+ * a `VirtualMachineCallback` for the VM, its `onPayloadFinished` method will be
+ * called with the VM's exit code.
+ *
+ * \return the exit code of the VM.
+ */
 extern int AVmPayload_main(void);
 #endif