2lib: Load Android kernel

This patchset adds possibility to boot Android kernel. If highest
priority partition entry type matches Android VBMETA guid, then
bootloader tries to load and boot Android.

BUG=b:309426555
TEST=Build FW and boot android
TEST=Use description from b/309426555#comment3
BRANCH=main

Signed-off-by: Konrad Adamczyk <konrada@google.com>
Signed-off-by: Jan Dabros <dabros@google.com>
Signed-off-by: Grzegorz Bernacki <bernacki@google.com>

Change-Id: Icf7c05549489b5d9b87a32806efd939e51f9a96d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/6281346
Reviewed-by: Julius Werner <jwerner@chromium.org>
Commit-Queue: Grzegorz Bernacki <bernacki@google.com>
Tested-by: Grzegorz Bernacki <bernacki@google.com>
Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
diff --git a/firmware/2lib/2load_kernel.c b/firmware/2lib/2load_kernel.c
index 0e3be85..d86b709 100644
--- a/firmware/2lib/2load_kernel.c
+++ b/firmware/2lib/2load_kernel.c
@@ -8,6 +8,9 @@
 
 #include "2api.h"
 #include "2common.h"
+#ifdef USE_LIBAVB
+#include "2load_android_kernel.h"
+#endif
 #include "2misc.h"
 #include "2nvstorage.h"
 #include "2packed_key.h"
@@ -314,7 +317,7 @@
 }
 
 /**
- * Load and verify a partition from the stream.
+ * Load and verify a ChromeOS kernel partition from the stream.
  *
  * @param ctx			Vboot context
  * @param params		Load-kernel parameters
@@ -323,10 +326,9 @@
  * @param kernel_version	The kernel version of this partition.
  * @return VB2_SUCCESS, or non-zero error code.
  */
-static vb2_error_t vb2_load_partition(struct vb2_context *ctx,
-				      struct vb2_kernel_params *params,
-				      VbExStream_t stream, uint32_t lpflags,
-				      uint32_t *kernel_version)
+static vb2_error_t vb2_load_chromeos_kernel(
+	struct vb2_context *ctx, struct vb2_kernel_params *params,
+	VbExStream_t stream, uint32_t lpflags, uint32_t *kernel_version)
 {
 	uint32_t read_ms = 0, start_ts;
 	struct vb2_workbuf wb;
@@ -457,8 +459,9 @@
 		return rv;
 	}
 
-	rv = vb2_load_partition(ctx, params, stream, lpflags, &kernel_version);
-	VB2_DEBUG("vb2_load_partition returned: %d\n", rv);
+	/* We are looking for ChromeOS partitions */
+	rv = vb2_load_chromeos_kernel(ctx, params, stream, lpflags, &kernel_version);
+	VB2_DEBUG("vb2_load_chromeos_kernel returned: %#x\n", rv);
 
 	VbExStreamClose(stream);
 
@@ -621,23 +624,14 @@
 		uint64_t part_start = entry->starting_lba;
 		uint64_t part_size = GptGetEntrySizeLba(entry);
 
-		VB2_DEBUG("Found kernel entry at %"
+		VB2_DEBUG("Found %s kernel entry at %"
 			  PRIu64 " size %" PRIu64 "\n",
+			  IsAndroid(entry) ? "Android" : "ChromeOS",
 			  part_start, part_size);
 
 		/* Found at least one kernel partition. */
 		found_partitions++;
 
-		/* Set up the stream */
-		VbExStream_t stream = NULL;
-		if (VbExStreamOpen(disk_info->handle,
-				   part_start, part_size, &stream)) {
-			VB2_DEBUG("Partition error getting stream.\n");
-			VB2_DEBUG("Marking kernel as invalid.\n");
-			GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
-			continue;
-		}
-
 		uint32_t lpflags = 0;
 		if (params->partition_number > 0) {
 			/*
@@ -648,9 +642,37 @@
 		}
 
 		uint32_t kernel_version = 0;
-		rv = vb2_load_partition(ctx, params, stream, lpflags,
-					&kernel_version);
-		VbExStreamClose(stream);
+		if (IsAndroid(entry)) {
+			/*
+			 * Android does not support versioning yet
+			 * TODO: b/324230492
+			 */
+			if (lpflags & VB2_LOAD_PARTITION_FLAG_VBLOCK_ONLY)
+				continue;
+#ifdef USE_LIBAVB
+			rv = vb2_load_android(ctx, &gpt, entry, params, disk_info->handle);
+#else
+			/* Don't allow to boot android without AVB */
+			rv = VB2_ERROR_LK_INVALID_KERNEL_FOUND;
+#endif
+		} else if (IsChromeOS(entry)) {
+			/* Set up the stream */
+			VbExStream_t stream = NULL;
+
+			if (VbExStreamOpen(disk_info->handle, part_start, part_size, &stream)) {
+				VB2_DEBUG("Partition error getting stream.\n");
+				VB2_DEBUG("Marking kernel as invalid.\n");
+				GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
+				continue;
+			}
+
+			/* Append status and try to load chromeos partition */
+			rv = vb2_load_chromeos_kernel(ctx, params, stream, lpflags,
+						      &kernel_version);
+			VbExStreamClose(stream);
+		} else {
+			rv = VB2_ERROR_LK_INVALID_KERNEL_FOUND;
+		}
 
 		if (rv) {
 			VB2_DEBUG("Marking kernel as invalid (err=%x).\n", rv);