Generate initrd & bootconfigs for Microdroid boot

Combine microdroid_ramdisk & microdroid_vendor_ramdisk images & this
will be microdroid_initrd in kernel_boot method. Also use the
initrd_bootconfig tool to attach bootconfig to it.

Also, collect all required bootconfigs. ABL, when verifying VBMeta, also
adds VBmeta digests & related configs to kernel command line. Without
ABL, we use bootconfig to send precomputed vbmeta digest. (Some of them
are computed using avbtool)

Test: Inspect the different build artifacts.
Bug: 240235424
Change-Id: I371c91db033a42bac6f0801a99490d18fc5dcdc1
diff --git a/apex/Android.bp b/apex/Android.bp
index 83985cc..a9fad55 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -63,6 +63,9 @@
     ],
     prebuilts: [
         "com.android.virt.init.rc",
+        "microdroid_initrd_app_debuggable",
+        "microdroid_initrd_full_debuggable",
+        "microdroid_initrd_normal",
         "microdroid.json",
         "microdroid_bootloader",
         "microdroid_bootloader.avbpubkey",
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 65aeb07..281416b 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -578,3 +578,18 @@
     filename: "event-log-tags",
     installable: false,
 }
+
+filegroup {
+    name: "microdroid_bootconfig_full_debuggable_src",
+    srcs: ["bootconfig.full_debuggable"],
+}
+
+filegroup {
+    name: "microdroid_bootconfig_app_debuggable_src",
+    srcs: ["bootconfig.app_debuggable"],
+}
+
+filegroup {
+    name: "microdroid_bootconfig_normal_src",
+    srcs: ["bootconfig.normal"],
+}
diff --git a/microdroid/initrd/Android.bp b/microdroid/initrd/Android.bp
index 147c963..a9d0da3 100644
--- a/microdroid/initrd/Android.bp
+++ b/microdroid/initrd/Android.bp
@@ -11,3 +11,151 @@
     ],
     prefer_rlib: true,
 }
+
+python_binary_host {
+    name: "gen_vbmeta_bootconfig",
+    srcs: ["gen_vbmeta_bootconfig.py"],
+}
+
+genrule {
+    name: "microdroid_initrd_gen",
+    srcs: [
+        ":microdroid_ramdisk",
+        ":microdroid_vendor_ramdisk",
+    ],
+    out: ["microdroid_initrd.img"],
+    cmd: "cat $(in) > $(out)",
+}
+
+// This contains vbmeta hashes & related (boot)configs which are passed to kernel/init
+genrule {
+    name: "microdroid_vbmeta_bootconfig_gen",
+    srcs: [":microdroid_vbmeta"],
+    out: ["bootconfig_microdroid_vbmeta"],
+    tools: [
+        "gen_vbmeta_bootconfig",
+        "avbtool",
+    ],
+    cmd: "$(location gen_vbmeta_bootconfig) $(location avbtool) $(in) > $(out)",
+}
+
+bootconfigs_arm64 = [
+    ":microdroid_bootconfig_arm64_gen",
+    ":microdroid_vbmeta_bootconfig_gen",
+]
+
+bootconfigs_x86_64 = [
+    ":microdroid_bootconfig_x86_64_gen",
+    ":microdroid_vbmeta_bootconfig_gen",
+]
+
+genrule {
+    name: "microdroid_initrd_full_debuggable_arm64",
+    tools: ["initrd_bootconfig"],
+    srcs: [
+        ":microdroid_initrd_gen",
+        ":microdroid_bootconfig_full_debuggable_src",
+    ] + bootconfigs_arm64,
+    out: ["microdroid_initrd_full_debuggable_arm64"],
+    cmd: "$(location initrd_bootconfig) --output $(out) $(in)",
+}
+
+genrule {
+    name: "microdroid_initrd_full_debuggable_x86_64",
+    tools: ["initrd_bootconfig"],
+    srcs: [
+        ":microdroid_initrd_gen",
+        ":microdroid_bootconfig_full_debuggable_src",
+    ] + bootconfigs_x86_64,
+    out: ["microdroid_initrd_full_debuggable_x86_64"],
+    cmd: "$(location initrd_bootconfig) --output $(out) $(in)",
+}
+
+genrule {
+    name: "microdroid_initrd_app_debuggable_arm64",
+    tools: ["initrd_bootconfig"],
+    srcs: [
+        ":microdroid_initrd_gen",
+        ":microdroid_bootconfig_app_debuggable_src",
+    ] + bootconfigs_arm64,
+    out: ["microdroid_initrd_app_debuggable_arm64"],
+    cmd: "$(location initrd_bootconfig) --output $(out) $(in)",
+}
+
+genrule {
+    name: "microdroid_initrd_app_debuggable_x86_64",
+    tools: ["initrd_bootconfig"],
+    srcs: [
+        ":microdroid_initrd_gen",
+        ":microdroid_bootconfig_app_debuggable_src",
+    ] + bootconfigs_x86_64,
+    out: ["microdroid_initrd_app_debuggable_x86_64"],
+    cmd: "$(location initrd_bootconfig) --output $(out) $(in)",
+}
+
+genrule {
+    name: "microdroid_initrd_normal_arm64",
+    tools: ["initrd_bootconfig"],
+    srcs: [
+        ":microdroid_initrd_gen",
+        ":microdroid_bootconfig_normal_src",
+    ] + bootconfigs_arm64,
+    out: ["microdroid_initrd_normal_arm64"],
+    cmd: "$(location initrd_bootconfig) --output $(out) $(in)",
+}
+
+genrule {
+    name: "microdroid_initrd_normal_x86_64",
+    tools: ["initrd_bootconfig"],
+    srcs: [
+        ":microdroid_initrd_gen",
+        ":microdroid_bootconfig_normal_src",
+    ] + bootconfigs_x86_64,
+    out: ["microdroid_initrd_normal_x86_64"],
+    cmd: "$(location initrd_bootconfig) --output $(out) $(in)",
+}
+
+prebuilt_etc {
+    name: "microdroid_initrd_full_debuggable",
+    // We don't have ramdisk for architectures other than x86_64 & arm64
+    src: "empty_file",
+    arch: {
+        x86_64: {
+            src: ":microdroid_initrd_full_debuggable_x86_64",
+        },
+        arm64: {
+            src: ":microdroid_initrd_full_debuggable_arm64",
+        },
+    },
+    filename: "microdroid_initrd_full_debuggable.img",
+}
+
+prebuilt_etc {
+    name: "microdroid_initrd_app_debuggable",
+    // We don't have ramdisk for architectures other than x86_64 & arm64
+    src: "empty_file",
+    arch: {
+        x86_64: {
+            src: ":microdroid_initrd_app_debuggable_x86_64",
+        },
+        arm64: {
+            src: ":microdroid_initrd_app_debuggable_arm64",
+        },
+    },
+    filename: "microdroid_initrd_app_debuggable.img",
+}
+
+prebuilt_etc {
+    name: "microdroid_initrd_normal",
+    // We don't have ramdisk for architectures other than x86_64 & arm64
+    src: "empty_file",
+    arch: {
+        x86_64: {
+            src: ":microdroid_initrd_normal_x86_64",
+        },
+        arm64: {
+            src: ":microdroid_initrd_normal_arm64",
+        },
+    },
+    filename: "microdroid_initrd_normal.img",
+}
diff --git a/microdroid/initrd/empty_file b/microdroid/initrd/empty_file
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/microdroid/initrd/empty_file
diff --git a/microdroid/initrd/gen_vbmeta_bootconfig.py b/microdroid/initrd/gen_vbmeta_bootconfig.py
new file mode 100755
index 0000000..f0fc2e8
--- /dev/null
+++ b/microdroid/initrd/gen_vbmeta_bootconfig.py
@@ -0,0 +1,54 @@
+"""Extract information about vbmeta (digest/size) required in (androidboot.*)
+bootconfig. It uses avbtool to find some values such as vbmeta size, digest"""
+#!/usr/bin/env python3
+
+import sys
+import subprocess
+
+def main(args):
+    """Runs avbtool to generate vbmeta related bootconfigs"""
+    avbtool = args[0]
+    vbmeta_img = args[1]
+    hash_algorithm = 'sha256'
+    size = 0
+
+    with subprocess.Popen([avbtool, 'version'],
+                            stdout=subprocess.PIPE,
+                            stderr=subprocess.STDOUT) as proc:
+        stdout, _ = proc.communicate()
+        avb_version = stdout.decode("utf-8").split(" ")[1].strip()
+        avb_version = avb_version[0:avb_version.rfind('.')]
+
+    with subprocess.Popen([avbtool, 'info_image', '--image', vbmeta_img],
+                           stdout=subprocess.PIPE,
+                           stderr=subprocess.STDOUT) as proc:
+        stdout, _ = proc.communicate()
+        for line in stdout.decode("utf-8").split("\n"):
+            line = line.split(":")
+            if line[0] in \
+                ['Header Block', 'Authentication Block', 'Auxiliary Block']:
+                size += int(line[1].strip()[0:-6])
+
+    with subprocess.Popen([avbtool, 'calculate_vbmeta_digest',
+                            '--image', vbmeta_img,
+                            '--hash_algorithm', hash_algorithm],
+                           stdout=subprocess.PIPE,
+                           stderr=subprocess.STDOUT) as proc:
+        stdout, _ = proc.communicate()
+        vbmeta_hash = stdout.decode("utf-8").strip()
+
+    print(f'androidboot.vbmeta.size = {size}')
+    print(f'androidboot.vbmeta.digest = \"{vbmeta_hash}\"')
+    print(f'androidboot.vbmeta.hash_alg = \"{hash_algorithm}\"')
+    print(f'androidboot.vbmeta.avb_version = \"{avb_version}\"')
+    print('androidboot.veritymode = "enforcing"')
+    print('androidboot.vbmeta.invalidate_on_error = "yes"')
+    print('androidboot.vbmeta.device_state = "locked"')
+    print('androidboot.vbmeta.device = "/dev/block/by-name/vbmeta_a"')
+    print('androidboot.slot_suffix = "_a"')
+    print('androidboot.force_normal_boot = "1"')
+    print('androidboot.verifiedbootstate = "green"')
+
+## Main body
+if __name__ == '__main__':
+    main(sys.argv[1:])