vmbase_example: Add support for kernel mode & test

Support linking vmbase_example as a payload compatible with crosvm's
"kernel" (default) mode.

Extend vmbase_example.integration_test to replicate the BIOS mode tests
in kernel mode, with the respective corresponding vmbase_example builds.

Bug: 359659124
Test: atest vmbase_example.integration_test
Change-Id: Ib125d46d703b62b2d65a3d4a6691d046720f1343
diff --git a/guest/vmbase_example/Android.bp b/guest/vmbase_example/Android.bp
index 86a63b7..ff7bd83 100644
--- a/guest/vmbase_example/Android.bp
+++ b/guest/vmbase_example/Android.bp
@@ -52,6 +52,12 @@
     cflags: ["-DVMBASE_EXAMPLE_IS_BIOS"],
 }
 
+cc_object {
+    name: "vmbase_example_kernel.ld",
+    defaults: ["vmbase_example_ld_defaults"],
+    cflags: ["-DVMBASE_EXAMPLE_IS_KERNEL"],
+}
+
 cc_defaults {
     name: "vmbase_example_elf_defaults",
     defaults: ["vmbase_elf_defaults"],
@@ -73,6 +79,16 @@
     ],
 }
 
+cc_binary {
+    name: "vmbase_example_kernel",
+    defaults: ["vmbase_example_elf_defaults"],
+    asflags: ["-DVMBASE_EXAMPLE_IS_KERNEL"],
+    linker_scripts: [
+        ":vmbase_example_kernel.ld",
+        ":vmbase_sections",
+    ],
+}
+
 raw_binary {
     name: "vmbase_example_bios_bin",
     stem: "vmbase_example_bios.bin",
@@ -84,3 +100,15 @@
         },
     },
 }
+
+raw_binary {
+    name: "vmbase_example_kernel_bin",
+    stem: "vmbase_example_kernel.bin",
+    src: ":vmbase_example_kernel",
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+}
diff --git a/guest/vmbase_example/idmap.S b/guest/vmbase_example/idmap.S
index 2e62085..881850c 100644
--- a/guest/vmbase_example/idmap.S
+++ b/guest/vmbase_example/idmap.S
@@ -49,6 +49,10 @@
 	.quad		.L_BLOCK_MEM_XIP | 0x80200000	// 2 MiB of DRAM containing image
 	.quad		.L_BLOCK_MEM | 0x80400000	// 2 MiB of writable DRAM
 	.fill		509, 8, 0x0
+#elif defined(VMBASE_EXAMPLE_IS_KERNEL)
+	.quad		.L_BLOCK_MEM_XIP | 0x80000000	// 2 MiB of DRAM containing image
+	.quad		.L_BLOCK_MEM | 0x80200000	// 2 MiB of writable DRAM
+	.fill		510, 8, 0x0
 #else
 #error "Unexpected vmbase_example mode: failed to generate idmap"
 #endif
diff --git a/guest/vmbase_example/image.ld.S b/guest/vmbase_example/image.ld.S
index 3bfab9c..a5cd965 100644
--- a/guest/vmbase_example/image.ld.S
+++ b/guest/vmbase_example/image.ld.S
@@ -19,6 +19,9 @@
 #if defined(VMBASE_EXAMPLE_IS_BIOS)
 	image		: ORIGIN = 0x80200000, LENGTH = 2M
 	writable_data	: ORIGIN = 0x80400000, LENGTH = 2M
+#elif defined(VMBASE_EXAMPLE_IS_KERNEL)
+	image		: ORIGIN = 0x80000000, LENGTH = 2M
+	writable_data	: ORIGIN = 0x80200000, LENGTH = 2M
 #else
 #error "Unexpected vmbase_example mode: failed to generate image layout"
 #endif
diff --git a/tests/vmbase_example/Android.bp b/tests/vmbase_example/Android.bp
index d652196..4c1aa30 100644
--- a/tests/vmbase_example/Android.bp
+++ b/tests/vmbase_example/Android.bp
@@ -19,6 +19,7 @@
     ],
     data: [
         ":vmbase_example_bios_bin",
+        ":vmbase_example_kernel_bin",
     ],
     test_suites: ["general-tests"],
     enabled: false,
diff --git a/tests/vmbase_example/src/main.rs b/tests/vmbase_example/src/main.rs
index de704fa..e0563b7 100644
--- a/tests/vmbase_example/src/main.rs
+++ b/tests/vmbase_example/src/main.rs
@@ -31,17 +31,27 @@
 };
 use vmclient::{DeathReason, VmInstance};
 
+const VMBASE_EXAMPLE_KERNEL_PATH: &str = "vmbase_example_kernel.bin";
 const VMBASE_EXAMPLE_BIOS_PATH: &str = "vmbase_example_bios.bin";
 const TEST_DISK_IMAGE_PATH: &str = "test_disk.img";
 const EMPTY_DISK_IMAGE_PATH: &str = "empty_disk.img";
 
+/// Runs the vmbase_example VM as an unprotected VM kernel via VirtualizationService.
+#[test]
+fn test_run_example_kernel_vm() -> Result<(), Error> {
+    run_test(Some(open_payload(VMBASE_EXAMPLE_KERNEL_PATH)?), None)
+}
+
 /// Runs the vmbase_example VM as an unprotected VM BIOS via VirtualizationService.
 #[test]
 fn test_run_example_bios_vm() -> Result<(), Error> {
-    run_test(Some(open_payload(VMBASE_EXAMPLE_BIOS_PATH)?))
+    run_test(None, Some(open_payload(VMBASE_EXAMPLE_BIOS_PATH)?))
 }
 
-fn run_test(bootloader: Option<ParcelFileDescriptor>) -> Result<(), Error> {
+fn run_test(
+    kernel: Option<ParcelFileDescriptor>,
+    bootloader: Option<ParcelFileDescriptor>,
+) -> Result<(), Error> {
     android_logger::init_once(
         android_logger::Config::default()
             .with_tag("vmbase")
@@ -89,7 +99,7 @@
 
     let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
         name: String::from("VmBaseTest"),
-        kernel: None,
+        kernel,
         initrd: None,
         params: None,
         bootloader,