Merge "app: aboot: Add support for bootimage containing a uncompressed kernel"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index fc41a24..99dca48 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -143,6 +143,14 @@
 
 #define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
 
+//Size of the header that is used in case the boot image has
+//a uncompressed kernel + appended dtb
+#define PATCHED_KERNEL_HEADER_SIZE 20
+
+//String used to determine if the boot image has
+//a uncompressed kernel + appended dtb
+#define PATCHED_KERNEL_MAGIC "UNCOMPRESSED_IMG"
+
 #if USE_BOOTDEV_CMDLINE
 static const char *emmc_cmdline = " androidboot.bootdevice=";
 #else
@@ -1069,8 +1077,8 @@
 	uint32_t dtb_offset = 0;
 	unsigned char *kernel_start_addr = NULL;
 	unsigned int kernel_size = 0;
+	unsigned int patched_kernel_hdr_size = 0;
 	int rc;
-
 #if DEVICE_TREE
 	struct dt_table *table;
 	struct dt_entry dt_entry;
@@ -1295,9 +1303,30 @@
 		kernel_start_addr = out_addr;
 		kernel_size = out_len;
 	} else {
-		kptr = (struct kernel64_hdr *)(image_addr + page_size);
-		kernel_start_addr = (unsigned char *)(image_addr + page_size);
-		kernel_size = hdr->kernel_size;
+		dprintf(INFO, "Uncpmpressed kernel in use\n");
+		if (!strncmp((char*)(image_addr + page_size),
+					PATCHED_KERNEL_MAGIC,
+					sizeof(PATCHED_KERNEL_MAGIC) - 1)) {
+			dprintf(INFO, "Patched kernel detected\n");
+			kptr = (struct kernel64_hdr *)(image_addr + page_size +
+					PATCHED_KERNEL_HEADER_SIZE);
+			//The size of the kernel is stored at start of kernel image + 16
+			//The dtb would start just after the kernel
+			dtb_offset = *((uint32_t*)((unsigned char*)
+						(image_addr + page_size +
+						 sizeof(PATCHED_KERNEL_MAGIC) -
+						 1)));
+			//The actual kernel starts after the 20 byte header.
+			kernel_start_addr = (unsigned char*)(image_addr +
+					page_size + PATCHED_KERNEL_HEADER_SIZE);
+			kernel_size = hdr->kernel_size;
+			patched_kernel_hdr_size = PATCHED_KERNEL_HEADER_SIZE;
+		} else {
+			dprintf(INFO, "Kernel image not patched..Unable to locate dt offset\n");
+			kptr = (struct kernel64_hdr *)(image_addr + page_size);
+			kernel_start_addr = (unsigned char *)(image_addr + page_size);
+			kernel_size = hdr->kernel_size;
+		}
 	}
 
 	/*
@@ -1410,9 +1439,11 @@
 		 * Else update with the atags address in the kernel header
 		 */
 		void *dtb;
-		dtb = dev_tree_appended((void*)(image_addr + page_size),
-					hdr->kernel_size, dtb_offset,
-					(void *)hdr->tags_addr);
+		dtb = dev_tree_appended(
+				(void*)(image_addr + page_size +
+					patched_kernel_hdr_size),
+				hdr->kernel_size, dtb_offset,
+				(void *)hdr->tags_addr);
 		if (!dtb) {
 			dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
 			return -1;