app: aboot: add new boot iamge header v2 support

In boot image header v2 dtb will be appended at the end
of boot image and dtb location will be passed via boot image header.
Add support for boot image header v2

Change-Id: I917ebafc3c361463f9791402f7debd82b6dd5bef
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
old mode 100644
new mode 100755
index 584ba35..c175208
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -210,6 +210,9 @@
 
 #define MAX_DTBO_IDX_STR 64
 static const char *android_boot_dtbo_idx = " androidboot.dtbo_idx=";
+
+#define MAX_DTB_IDX_STR MAX_DTBO_IDX_STR
+static const char *android_boot_dtb_idx = " androidboot.dtb_idx=";
 #endif
 
 #if VERIFIED_BOOT
@@ -453,6 +456,8 @@
 	int syspath_buflen = strlen(sys_path) + sizeof(int) + 2; /*allocate buflen for largest possible string*/
 	char dtbo_idx_str[MAX_DTBO_IDX_STR] = "\0";
 	int dtbo_idx = INVALID_PTN;
+	char dtb_idx_str[MAX_DTB_IDX_STR] = "\0";
+	int dtb_idx = INVALID_PTN;
 #endif
 	char syspath_buf[syspath_buflen];
 #if HIBERNATION_SUPPORT
@@ -712,6 +717,13 @@
 			android_boot_dtbo_idx, dtbo_idx);
 		cmdline_len += strlen (dtbo_idx_str);
 	}
+
+	dtb_idx = get_dtb_idx ();
+	if (dtb_idx != INVALID_PTN) {
+		snprintf(dtb_idx_str, sizeof(dtb_idx_str), "%s%d",
+				 android_boot_dtb_idx, dtb_idx);
+		cmdline_len += strlen (dtb_idx_str);
+	}
 #endif
 
 	if (cmdline_len > 0) {
@@ -992,6 +1004,12 @@
 			--dst;
 			while ((*dst++ = *src++));
 		}
+
+		if (dtb_idx != INVALID_PTN) {
+			src = dtb_idx_str;
+			--dst;
+			while ((*dst++ = *src++));
+		}
 #endif
 	}
 
@@ -1476,8 +1494,11 @@
 	unsigned ramdisk_actual;
 	unsigned imagesize_actual;
 	unsigned second_actual = 0;
+	void * image_buf = NULL;
 
 	unsigned int dtb_size = 0;
+	unsigned dtb_image_size = 0;
+	uint32_t dtb_image_offset = 0;
 	unsigned int out_len = 0;
 	unsigned int out_avai_len = 0;
 	unsigned char *out_addr = NULL;
@@ -1601,6 +1622,7 @@
 	}
 	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
 #endif
+	dtb_image_size = hdr->kernel_size;
 
 #ifdef OSVERSION_IN_BOOTIMAGE
 	/* If header version is ONE and booting into recovery,
@@ -1660,8 +1682,31 @@
 		dprintf(SPEW, "Recovery Dtbo Offset 0x%llx\n", hdr1->recovery_dtbo_offset);
 
 	}
+
+	if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
+		struct boot_img_hdr_v1 *hdr1 =
+			(struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
+		struct boot_img_hdr_v2 *hdr2 = (struct boot_img_hdr_v2 *)
+			(image_addr + sizeof(boot_img_hdr) +
+			BOOT_IMAGE_HEADER_V2_OFFSET);
+		unsigned int recovery_dtbo_actual = 0;
+
+		imagesize_actual += ROUND_TO_PAGE(hdr1->recovery_dtbo_size,
+					page_mask);
+
+		imagesize_actual += ROUND_TO_PAGE(hdr2->dtb_size, page_mask);
+
+
+		dtb_image_offset = page_size + patched_kernel_hdr_size +
+				   kernel_actual + ramdisk_actual + second_actual +
+				   recovery_dtbo_actual;
+
+		dprintf(SPEW, "Header version: %d\n", hdr->header_version);
+		dprintf(SPEW, "Dtb image offset 0x%x\n", dtb_image_offset);
+	}
 #endif
 
+
 	/* Validate the boot/recovery image size is within the bounds of partition size */
 	if (imagesize_actual > image_size) {
 		dprintf(CRITICAL, "Image size is greater than partition size.\n");
@@ -2047,10 +2092,16 @@
 		 * In case of dtbo, this API is going to read dtbo on scratch.
 		 */
 		void *dtb;
-		dtb = dev_tree_appended(
-				(void*)(image_addr + page_size +
-					patched_kernel_hdr_size),
-				hdr->kernel_size, dtb_offset,
+		image_buf = (void*)(image_addr + page_size + patched_kernel_hdr_size);
+
+		if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
+
+			image_buf = (void*)(image_addr);
+			dtb_offset = dtb_image_offset;
+			dtb_image_size = imagesize_actual;
+		}
+
+		dtb = dev_tree_appended(image_buf, dtb_image_size, dtb_offset,
 				(void *)hdr->tags_addr);
 		if (!dtb) {
 			dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
diff --git a/app/aboot/bootimg.h b/app/aboot/bootimg.h
index a07db93..1ad5a64 100644
--- a/app/aboot/bootimg.h
+++ b/app/aboot/bootimg.h
@@ -2,7 +2,7 @@
  * Copyright (C) 2008 The Android Open Source Project
  * All rights reserved.
  *
- * Copyright (c) 2014,2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014,2016,2019 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -154,6 +154,50 @@
  *    else: jump to kernel_addr
  */
 
+#define BOOT_IMAGE_HEADER_V2_OFFSET sizeof (struct boot_img_hdr_v1)
+#define BOOT_HEADER_VERSION_TWO 2
+
+struct boot_img_hdr_v2 {
+    uint32_t dtb_size; /* size in bytes for DTB image */
+    uint64_t dtb_addr; /* physical load address for DTB image */
+} __attribute__((packed));
+
+/* When the boot image header has a version of BOOT_HEADER_VERSION_TWO,
+ * the structure of the boot image is as follows:
+ *
+ * +-----------------+
+ * | boot header     | 1 page
+ * +-----------------+
+ * | kernel          | n pages
+ * +-----------------+
+ * | ramdisk         | m pages
+ * +-----------------+
+ * | second stage    | o pages
+ * +-----------------+
+ * | recovery dtbo   | p pages
+ * +-----------------+
+ * | dtb.img         | q pages
+ * +-----------------+
+ * n = (kernel_size + page_size - 1) / page_size
+ * m = (ramdisk_size + page_size - 1) / page_size
+ * o = (second_size + page_size - 1) / page_size
+ * p = (recovery_dtbo_size + page_size - 1) / page_size
+ * q = (dtb_size + page_size - 1) / page_size
+ *
+ * 0. all entities are page_size aligned in flash
+ * 1. kernel and ramdisk are required (size != 0)
+ * 2. recovery_dtbo is required for recovery.img
+ *    in non-A/B devices(recovery_dtbo_size != 0)
+ * 3. second is optional (second_size == 0 -> no second)
+ * 4. load each element (kernel, ramdisk, second, recovery_dtbo) at
+ *    the specified physical address (kernel_addr, etc)
+ * 5. prepare tags at tag_addr.  kernel_args[] is
+ *    appended to the kernel commandline in the tags.
+ * 6. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
+ * 7. if second_size != 0: jump to second_addr
+ *    else: jump to kernel_addr
+ */
+
 boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size,
                         void *ramdisk, unsigned ramdisk_size,
                         void *second, unsigned second_size,