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"); +} +``` + +
+ +* 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. + +
+ +[1]: https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/master/vmbase/