From b2ce958f2e9f4be98faadfa8d8cfef54784eff50 Mon Sep 17 00:00:00 2001
From: Andrew Walbran <qwandor@google.com>
Date: Tue, 21 Mar 2023 17:03:02 +0000
Subject: [PATCH] Add pages about Android and vmbase.

---
 src/SUMMARY.md                   |  4 +--
 src/bare-metal/android.md        | 44 ++++++++++++++++++++++++++++++++
 src/bare-metal/android/vmbase.md | 27 ++++++++++++++++++++
 3 files changed, 73 insertions(+), 2 deletions(-)
 create mode 100644 src/bare-metal/android.md
 create mode 100644 src/bare-metal/android/vmbase.md

diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index 22c25af6..4d204af0 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -274,8 +274,8 @@
   - [buddy_system_allocator](bare-metal/useful-crates/buddy_system_allocator.md)
   - [tinyvec](bare-metal/useful-crates/tinyvec.md)
   - [spin](bare-metal/useful-crates/spin.md)
-- [Android]()
-  - [vmbase]()
+- [Android](bare-metal/android.md)
+  - [vmbase](bare-metal/android/vmbase.md)
 - [Exercises](exercises/bare-metal/afternoon.md)
   - [RTC driver](exercises/bare-metal/rtc.md)
 
diff --git a/src/bare-metal/android.md b/src/bare-metal/android.md
new file mode 100644
index 00000000..c5fb523b
--- /dev/null
+++ b/src/bare-metal/android.md
@@ -0,0 +1,44 @@
+# Android
+
+To build a bare-metal Rust binary in AOSP, you need to use a `rust_ffi_static` Soong rule to build
+your Rust code, then a `cc_binary` with a linker script to produce the binary itself, and then a
+`raw_binary` to convert the ELF to a raw binary ready to be run.
+
+```soong
+rust_ffi_static {
+    name: "libvmbase_example",
+    defaults: ["vmbase_ffi_defaults"],
+    crate_name: "vmbase_example",
+    srcs: ["src/main.rs"],
+    rustlibs: [
+        "libvmbase",
+    ],
+}
+
+cc_binary {
+    name: "vmbase_example",
+    defaults: ["vmbase_elf_defaults"],
+    srcs: [
+        "idmap.S",
+    ],
+    static_libs: [
+        "libvmbase_example",
+    ],
+    linker_scripts: [
+        "image.ld",
+        ":vmbase_sections",
+    ],
+}
+
+raw_binary {
+    name: "vmbase_example_bin",
+    stem: "vmbase_example.bin",
+    src: ":vmbase_example",
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+}
+```
diff --git a/src/bare-metal/android/vmbase.md b/src/bare-metal/android/vmbase.md
new file mode 100644
index 00000000..2e70dc23
--- /dev/null
+++ b/src/bare-metal/android/vmbase.md
@@ -0,0 +1,27 @@
+# vmbase
+
+For VMs running under crosvm on aarch64, the [vmbase][1] library provides a linker script and useful
+defaults for the build rules, along with an entry point, UART console logging and more.
+
+```rust,compile_fail
+#![no_main]
+#![no_std]
+
+use vmbase::{main, println};
+
+main!(main);
+
+pub fn main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) {
+    println!("Hello world");
+}
+```
+
+<details>
+
+* The `main!` macro marks your main function, to be called from the `vmbase` entry point.
+* The `vmbase` entry point handles console initialisation, and issues a PSCI_SYSTEM_OFF to shutdown
+  the VM if your main function returns.
+
+</details>
+
+[1]: https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/master/vmbase/