Merge "platform: msm8952: Add platform support for QM215"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index e194f85..930621e 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -248,6 +248,9 @@
static uint32_t dt_size = 0;
static char *vbcmdline;
static bootinfo info = {0};
+static void *recovery_dtbo_buf = NULL;
+static uint32_t recovery_dtbo_size = 0;
+
/* Assuming unauthorized kernel image by default */
static int auth_kernel_img = 0;
static device_info device = {DEVICE_MAGIC,0,0,0,0,{0},{0},{0},1,{0},0,{0}};
@@ -345,7 +348,7 @@
extern int fastboot_trigger(void);
#endif
-static void update_ker_tags_rdisk_addr(struct boot_img_hdr *hdr, bool is_arm64)
+static void update_ker_tags_rdisk_addr(boot_img_hdr *hdr, bool is_arm64)
{
/* overwrite the destination of specified for the project */
#ifdef ABOOT_IGNORE_BOOT_HEADER_ADDRS
@@ -370,6 +373,50 @@
memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry));
*ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned);
}
+#ifdef VERIFIED_BOOT_2
+void load_vbmeta_image(void **vbmeta_image_buf, uint32_t *vbmeta_image_sz)
+{
+ int index = 0;
+ char *vbm_img_buf = NULL;
+ unsigned long long ptn = 0;
+ unsigned long long ptn_size = 0;
+
+ /* Immediately return if dtbo is not supported */
+ index = partition_get_index("vbmeta");
+ ptn = partition_get_offset(index);
+ if(!ptn)
+ {
+ dprintf(CRITICAL, "ERROR: vbmeta partition not found.\n");
+ return;
+ }
+
+ ptn_size = partition_get_size(index);
+ if (ptn_size > MAX_SUPPORTED_VBMETA_IMG_BUF)
+ {
+ dprintf(CRITICAL, "ERROR: vbmeta parition size is greater than supported.\n");
+ return;
+ }
+
+ vbm_img_buf = (char *)memalign(CACHE_LINE, ROUNDUP((uint32_t)ptn_size, CACHE_LINE));
+ if (!vbm_img_buf)
+ {
+ dprintf(CRITICAL, "ERROR: vbmeta unable to locate buffer\n");
+ return;
+ }
+
+ mmc_set_lun(partition_get_lun(index));
+ if (mmc_read(ptn, (uint32_t *)vbm_img_buf, (uint32_t)ptn_size))
+ {
+ dprintf(CRITICAL, "ERROR: vbmeta read failure\n");
+ free(vbm_img_buf);
+ return;
+ }
+
+ *vbmeta_image_buf = vbm_img_buf;
+ *vbmeta_image_sz = (uint32_t)ptn_size;
+ return;
+}
+#endif
#if CHECK_BAT_VOLTAGE
void update_battery_status(void)
@@ -1189,6 +1236,9 @@
strlen(imgname))) {
*image_buffer = info.images[loadedindex].image_buffer;
*imgsize = info.images[loadedindex].imgsize;
+ dprintf(SPEW, "getimage(): Loaded image [%s|%d]\n",
+ info.images[loadedindex].name,
+ info.images[loadedindex].imgsize);
return 0;
}
}
@@ -1378,10 +1428,18 @@
}
}
+/* Function to return recovery appended dtbo buffer info */
+void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf)
+{
+ *dtbo_size = recovery_dtbo_size;
+ *dtbo_buf = recovery_dtbo_buf;
+ return;
+}
+
int boot_linux_from_mmc(void)
{
- struct boot_img_hdr *hdr = (void*) buf;
- struct boot_img_hdr *uhdr;
+ boot_img_hdr *hdr = (void*) buf;
+ boot_img_hdr *uhdr;
unsigned offset = 0;
int rcode;
unsigned long long ptn = 0;
@@ -1401,9 +1459,14 @@
unsigned char *kernel_start_addr = NULL;
unsigned int kernel_size = 0;
unsigned int patched_kernel_hdr_size = 0;
+ uint64_t image_size = 0;
int rc;
#if VERIFIED_BOOT_2
int status;
+ void *dtbo_image_buf = NULL;
+ uint32_t dtbo_image_sz = 0;
+ void *vbmeta_image_buf = NULL;
+ uint32_t vbmeta_image_sz = 0;
#endif
char *ptn_name = NULL;
#if DEVICE_TREE
@@ -1431,7 +1494,7 @@
boot_into_ffbm = true;
} else
boot_into_ffbm = false;
- uhdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
+ uhdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
dprintf(INFO, "Unified boot method!\n");
hdr = uhdr;
@@ -1448,7 +1511,8 @@
index = partition_get_index(ptn_name);
ptn = partition_get_offset(index);
- if(ptn == 0) {
+ image_size = partition_get_size(index);
+ if(ptn == 0 || image_size == 0) {
dprintf(CRITICAL, "ERROR: No %s partition found\n", ptn_name);
return -1;
}
@@ -1490,6 +1554,8 @@
#ifndef OSVERSION_IN_BOOTIMAGE
dt_size = hdr->dt_size;
#endif
+ dprintf(INFO, "BootImage Header: %d\n", hdr->header_version);
+
dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
@@ -1504,6 +1570,63 @@
imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
#endif
+#ifdef OSVERSION_IN_BOOTIMAGE
+ /* If header version is ONE and booting into recovery,
+ dtbo is appended with recovery image.
+ Doing following:
+ * Validating the recovery offset and size.
+ * Extracting recovery dtbo to be used as dtbo.
+ */
+ if (boot_into_recovery &&
+ hdr->header_version == BOOT_HEADER_VERSION_ONE)
+ {
+ struct boot_img_hdr_v1 *hdr1 =
+ (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
+
+ if ((hdr1->header_size !=
+ sizeof(struct boot_img_hdr_v1) + sizeof(boot_img_hdr)))
+ {
+ dprintf(CRITICAL, "Invalid boot image header: %d\n", hdr1->header_size);
+ return -1;
+ }
+
+ if (UINT_MAX < (hdr1->recovery_dtbo_offset + hdr1->recovery_dtbo_size)) {
+ dprintf(CRITICAL,
+ "Integer overflow detected in recovery image header fields at %u in %s\n",__LINE__,__FILE__);
+ return -1;
+ }
+
+ if (hdr1->recovery_dtbo_size > MAX_SUPPORTED_DTBO_IMG_BUF) {
+ dprintf(CRITICAL, "Recovery Dtbo Size too big %x, Allowed size %x\n", hdr1->recovery_dtbo_size,
+ MAX_SUPPORTED_DTBO_IMG_BUF);
+ return -1;
+ }
+
+ if (UINT_MAX < ((uint64_t)imagesize_actual + recovery_dtbo_size))
+ {
+ dprintf(CRITICAL, "Integer overflow detected in recoveryimage header fields at %u in %s\n",__LINE__,__FILE__);
+ return -1;
+ }
+
+ if (hdr1->recovery_dtbo_offset + recovery_dtbo_size > image_size)
+ {
+ dprintf(CRITICAL, "Invalid recovery dtbo: Recovery Dtbo Offset=0x%llx,"
+ " Recovery Dtbo Size=0x%x, Image Size=0x%llx\n",
+ hdr1->recovery_dtbo_offset, recovery_dtbo_size, image_size);
+ return -1;
+ }
+
+ recovery_dtbo_buf = (void *)(hdr1->recovery_dtbo_offset + image_addr);
+ recovery_dtbo_size = hdr1->recovery_dtbo_size;
+ imagesize_actual += recovery_dtbo_size;
+
+ dprintf(SPEW, "Header version: %d\n", hdr->header_version);
+ dprintf(SPEW, "Recovery Dtbo Size 0x%x\n", recovery_dtbo_size);
+ dprintf(SPEW, "Recovery Dtbo Offset 0x%llx\n", hdr1->recovery_dtbo_offset);
+
+ }
+#endif
+
#if VERIFIED_BOOT
boot_verifier_init();
#endif
@@ -1582,11 +1705,37 @@
return -1;
}
+ /* load and validate dtbo partition */
+ load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
+
+ /* load vbmeta partition */
+ load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
+
memset(&info, 0, sizeof(bootinfo));
- info.images[0].image_buffer = image_addr;
- info.images[0].imgsize = imagesize_actual;
- info.images[0].name = "boot";
- info.num_loaded_images = 0;
+
+ /* Pass loaded boot image passed */
+ info.images[IMG_BOOT].image_buffer = image_addr;
+ info.images[IMG_BOOT].imgsize = imagesize_actual;
+ info.images[IMG_BOOT].name = ptn_name;
+ ++info.num_loaded_images;
+
+ /* Pass loaded dtbo image */
+ if (dtbo_image_buf != NULL) {
+ info.images[IMG_DTBO].image_buffer = dtbo_image_buf;
+ info.images[IMG_DTBO].imgsize = dtbo_image_sz;
+ info.images[IMG_DTBO].name = "dtbo";
+ ++info.num_loaded_images;
+ }
+
+ /* Pass loaded vbmeta image */
+ if (vbmeta_image_buf != NULL) {
+ info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
+ info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
+ info.images[IMG_VBMETA].name = "vbmeta";
+ ++info.num_loaded_images;
+ }
+
+ info.header_version = hdr->header_version;
info.multi_slot_boot = partition_multislot_is_supported();
info.bootreason_alarm = boot_reason_alarm;
info.bootinto_recovery = boot_into_recovery;
@@ -1595,6 +1744,10 @@
return -1;
vbcmdline = info.vbcmdline;
+
+ /* Free the buffer allocated to vbmeta post verification */
+ free(vbmeta_image_buf);
+ --info.num_loaded_images;
#else
/* Change the condition a little bit to include the test framework support.
* We would never reach this point if device is in fastboot mode, even if we did
@@ -1677,6 +1830,10 @@
{
out_addr = (unsigned char *)(image_addr + imagesize_actual + page_size);
out_avai_len = target_get_max_flash_size() - imagesize_actual - page_size;
+#if VERIFIED_BOOT_2
+ if (dtbo_image_sz)
+ out_avai_len -= DTBO_IMG_BUF;
+#endif
dprintf(INFO, "decompressing kernel image: start\n");
rc = decompress((unsigned char *)(image_addr + page_size),
hdr->kernel_size, out_addr, out_avai_len,
@@ -1859,7 +2016,7 @@
int boot_linux_from_flash(void)
{
- struct boot_img_hdr *hdr = (void*) buf;
+ boot_img_hdr *hdr = (void*) buf;
struct ptentry *ptn;
struct ptable *ptable;
unsigned offset = 0;
@@ -1882,7 +2039,7 @@
#endif
if (target_is_emmc_boot()) {
- hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
+ hdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
return -1;
@@ -2667,7 +2824,7 @@
unsigned char *best_match_dt_addr = NULL;
int rc;
- struct boot_img_hdr *hdr = (struct boot_img_hdr *) (boot_image_start);
+ boot_img_hdr *hdr = (boot_img_hdr *) (boot_image_start);
#ifndef OSVERSION_IN_BOOTIMAGE
dt_size = hdr->dt_size;
@@ -2755,7 +2912,7 @@
unsigned second_actual;
uint32_t image_actual;
uint32_t dt_actual = 0;
- struct boot_img_hdr *hdr = NULL;
+ boot_img_hdr *hdr = NULL;
struct kernel64_hdr *kptr = NULL;
char *ptr = ((char*) data);
int ret = 0;
@@ -2793,7 +2950,7 @@
goto boot_failed;
}
- hdr = (struct boot_img_hdr *)data;
+ hdr = (boot_img_hdr *)data;
/* ensure commandline is terminated */
hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
diff --git a/app/aboot/bootimg.h b/app/aboot/bootimg.h
index 7dfbef8..a07db93 100644
--- a/app/aboot/bootimg.h
+++ b/app/aboot/bootimg.h
@@ -31,16 +31,19 @@
#ifndef _BOOT_IMAGE_H_
#define _BOOT_IMAGE_H_
-typedef struct boot_img_hdr boot_img_hdr;
-
#define BOOT_MAGIC "ANDROID!"
#define BOOT_MAGIC_SIZE 8
#define BOOT_NAME_SIZE 16
#define BOOT_ARGS_SIZE 512
#define BOOT_IMG_MAX_PAGE_SIZE 4096
+#define BOOT_EXTRA_ARGS_SIZE 1024
-struct boot_img_hdr
-{
+#define BOOT_HEADER_VERSION_ZERO 0
+/* Struct def for boot image header
+ * Bootloader expects the structure of boot_img_hdr with header version
+ * BOOT_HEADER_VERSION_ZERO to be as follows:
+ */
+struct boot_img_hdr_v0 {
unsigned char magic[BOOT_MAGIC_SIZE];
unsigned kernel_size; /* size in bytes */
@@ -55,7 +58,7 @@
unsigned tags_addr; /* physical addr for kernel tags */
unsigned page_size; /* flash page size we assume */
#if OSVERSION_IN_BOOTIMAGE
- uint32_t unused; /* future expansion: should be 0 */
+ uint32_t header_version; /* version for the boot image header */
uint32_t os_version; /* version << 11 | patch_level */
#else
unsigned dt_size; /* device_tree in bytes */
@@ -66,7 +69,24 @@
unsigned char cmdline[BOOT_ARGS_SIZE];
unsigned id[8]; /* timestamp / checksum / sha1 / etc */
-};
+
+ /* Supplemental command line data; kept here to maintain
+ * binary compatibility with older versions of mkbootimg
+ */
+ uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
+} __attribute__((packed));
+
+/*
+ * It is expected that callers would explicitly specify which version of the
+ * boot image header they need to use.
+ */
+typedef struct boot_img_hdr_v0 boot_img_hdr;
+
+/**
+ * Offset of recovery DTBO length in a boot image header of version V1 or
+ * above.
+ */
+#define BOOT_IMAGE_HEADER_V1_RECOVERY_DTBO_SIZE_OFFSET sizeof (boot_img_hdr)
/*
** +-----------------+
@@ -78,13 +98,9 @@
** +-----------------+
** | second stage | o pages
** +-----------------+
-** | device tree | p 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 = (dt_size + page_size - 1) / page_size
** 0. all entities are page_size aligned in flash
** 1. kernel and ramdisk are required (size != 0)
** 2. second is optional (second_size == 0 -> no second)
@@ -97,6 +113,47 @@
** else: jump to kernel_addr
*/
+#define BOOT_HEADER_VERSION_ONE 1
+
+struct boot_img_hdr_v1 {
+ uint32_t recovery_dtbo_size; /* size in bytes for recovery DTBO image */
+ uint64_t recovery_dtbo_offset; /* physical load addr */
+ uint32_t header_size;
+} __attribute__((packed));
+
+/* When the boot image header has a version of BOOT_HEADER_VERSION_ONE,
+ * 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
+ * +-----------------+
+ * 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
+ *
+ * 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,
diff --git a/platform/msm_shared/avb/VerifiedBoot.c b/platform/msm_shared/avb/VerifiedBoot.c
index 5816d33..585d6a9 100644
--- a/platform/msm_shared/avb/VerifiedBoot.c
+++ b/platform/msm_shared/avb/VerifiedBoot.c
@@ -46,6 +46,7 @@
#define INTERMEDIATE_DIGEST_LENGTH 64
#define MAX_PART_NAME_SIZE 10
#define MAX_NUM_REQ_PARTITION 8
+#define BOOT_HEADER_VERSION_ZERO 0
char *avb_verify_partition_name[] = {
"boot",
@@ -372,6 +373,7 @@
CHAR8 *RequestedPartitionAll[MAX_NUM_REQ_PARTITION] = {NULL};
const CHAR8 **RequestedPartition = NULL;
UINTN NumRequestedPartition = 0;
+ UINT32 HeaderVersion = 0;
UINT32 ImageHdrSize = 0;
UINT32 imgsizeActual = 0;
VOID *image_buffer = NULL;
@@ -382,6 +384,7 @@
AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
device_info DevInfo_vb;
+ HeaderVersion = Info->header_version;
Info->boot_state = RED;
GUARD(VBCommonInit(Info));
@@ -416,15 +419,19 @@
if(!Info->multi_slot_boot && Info->bootinto_recovery) {
AddRequestedPartition(RequestedPartitionAll, IMG_RECOVERY);
NumRequestedPartition += 1;
+ /* Add dtbo validation if target supports dtbo image generation and
+ dtbo is not included in recovery i.e. HEADER VERSION is 0 */
+ if (is_target_support_dtbo() && HeaderVersion == BOOT_HEADER_VERSION_ZERO) {
+ AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
+ NumRequestedPartition += 1;
+ }
} else {
AddRequestedPartition(RequestedPartitionAll, IMG_BOOT);
NumRequestedPartition += 1;
- }
-
- /* Remove dtbo validation if target does not support dtbo image generation*/
- if (is_target_support_dtbo()) {
- AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
- NumRequestedPartition += 1;
+ if (is_target_support_dtbo()) {
+ AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
+ NumRequestedPartition += 1;
+ }
}
RequestedPartition = (const CHAR8 **)RequestedPartitionAll;
diff --git a/platform/msm_shared/avb/libavb/avb_slot_verify.c b/platform/msm_shared/avb/libavb/avb_slot_verify.c
index d709635..b279e22 100644
--- a/platform/msm_shared/avb/libavb/avb_slot_verify.c
+++ b/platform/msm_shared/avb/libavb/avb_slot_verify.c
@@ -158,20 +158,17 @@
}
}
- image_buf = (uint8_t *)target_get_scratch_address()+0x02000000;
+ if (!strncmp(part_name, "boot", strlen("boot"))) {
+ image_size = hash_desc.image_size;
+ }
+
+ io_ret = ops->read_from_partition(
+ ops, part_name, 0 /* offset */, image_size, &image_buf, &part_num_read);
+
if (image_buf == NULL) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto out;
}
-
- if (!strncmp(part_name, "boot", strlen("boot"))) {
- image_size = hash_desc.image_size;
- io_ret = ops->read_from_partition(
- ops, part_name, 0 /* offset */, image_size, &image_buf, &part_num_read);
- } else {
- io_ret = ops->read_from_partition(
- ops, part_name, 0 /* offset */, image_size, image_buf, &part_num_read);
- }
if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto out;
@@ -180,7 +177,7 @@
ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
goto out;
}
- if (part_num_read != image_size) {
+ if (part_num_read < image_size) {
avb_errorv(part_name, ": Read fewer than requested bytes.\n", NULL);
ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
goto out;
@@ -470,18 +467,17 @@
vbmeta_size = footer.vbmeta_size;
}
- vbmeta_buf = (uint8_t *)target_get_scratch_address() + 0x06000000;
+ io_ret = ops->read_from_partition(ops,
+ full_partition_name,
+ vbmeta_offset,
+ vbmeta_size,
+ &vbmeta_buf,
+ &vbmeta_num_read);
if (vbmeta_buf == NULL) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto out;
}
- io_ret = ops->read_from_partition(ops,
- full_partition_name,
- vbmeta_offset,
- vbmeta_size,
- vbmeta_buf,
- &vbmeta_num_read);
if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto out;
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index ced0fac..b81f3f2 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -421,7 +421,7 @@
ASSERT(0);
}
- if (version_rsp.major_version > 0x2)
+ if (version_rsp.major_version >= 0x2)
{
bs_req = malloc(sizeof(km_set_boot_state_req_t) + sizeof(km_boot_state_t));
ASSERT(bs_req);
@@ -782,11 +782,11 @@
#if OSVERSION_IN_BOOTIMAGE
void set_os_version(unsigned char* img_addr)
{
- struct boot_img_hdr *img_hdr = NULL;
+ boot_img_hdr *img_hdr = NULL;
/* Extract the os version and patch level */
if (img_addr) {
- img_hdr = (struct boot_img_hdr *)img_addr;
+ img_hdr = (boot_img_hdr *)img_addr;
boot_state_info.system_version = (img_hdr->os_version & 0xFFFFF800) >> 11;
boot_state_info.system_security_level = (img_hdr->os_version & 0x7FF);
} else {
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 12d39b3..6a99514 100644
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -176,77 +176,90 @@
dtbo_error ret = DTBO_SUCCESS;
static bool dtbo_loaded = false;
static unsigned long long ptn_size = 0;
+ uint32_t recovery_dtbo_size = 0;
+ void *recovery_appended_dtbo = NULL;
/* If dtbo loaded skip loading */
if (dtbo_loaded)
goto out;
- /* Immediately return if dtbo is not supported */
- index = partition_get_index("dtbo");
- if (index == INVALID_PTN)
- {
- ret = DTBO_NOT_SUPPORTED;
- goto out;
- }
+ get_recovery_dtbo_info(&recovery_dtbo_size, &recovery_appended_dtbo);
- ptn = partition_get_offset(index);
- if(!ptn)
- {
- dprintf(CRITICAL, "ERROR: dtbo parition failed to get offset. \n");
- ret = DTBO_ERROR;
- goto out;
- }
+ /* Intialize dtbo for recovery header v1 */
+ if (recovery_dtbo_size && recovery_appended_dtbo) {
+ dtbo_image_buf = recovery_appended_dtbo;
+ dtbo_partition_size = recovery_dtbo_size;
+ ptn_size = recovery_dtbo_size;
+ } else {
+ index = partition_get_index("dtbo");
- ptn_size = partition_get_size(index);
- if (ptn_size > MAX_SUPPORTED_DTBO_IMG_BUF)
- {
- dprintf(CRITICAL, "ERROR: dtbo parition size is greater than supported.\n");
- ret = DTBO_ERROR;
- goto out;
- }
-/*
- Read dtbo image into scratch region after kernel image.
- dtbo_image_buf_size = total_scratch_region_size - boot_img_sz
-*/
- boot_img_sz = partition_get_size(partition_get_index("boot"));
- if (!boot_img_sz)
- {
- dprintf(CRITICAL, "ERROR: Unable to get boot partition size\n");
- ret = DTBO_NOT_SUPPORTED;
- goto out;
- }
+ /* Immediately return if dtbo is not supported */
+ if (index == INVALID_PTN)
+ {
+ ret = DTBO_NOT_SUPPORTED;
+ goto out;
+ }
- dtbo_image_buf_size = target_get_max_flash_size() - boot_img_sz;
- dtbo_partition_size = ptn_size + ADDR_ALIGNMENT;
- dtbo_partition_size = ROUND_TO_PAGE(dtbo_partition_size, (page_size - 1)); /* Maximum dtbo size possible */
- if (dtbo_partition_size == UINT_MAX ||
- dtbo_image_buf_size < dtbo_partition_size)
- {
- dprintf(CRITICAL, "ERROR: Invalid DTBO partition size\n");
- ret = DTBO_NOT_SUPPORTED;
- goto out;
- }
+ ptn = partition_get_offset(index);
+ if(!ptn)
+ {
+ dprintf(CRITICAL, "ERROR: dtbo parition failed to get offset. \n");
+ ret = DTBO_ERROR;
+ goto out;
+ }
- mmc_set_lun(partition_get_lun(index));
- /* read dtbo at last 10MB of scratch */
- dtbo_image_buf = target_get_scratch_address() +
- (target_get_max_flash_size() - DTBO_IMG_BUF);
- dtbo_image_buf =
- (void *)ROUND_TO_PAGE((addr_t)dtbo_image_buf, (ADDR_ALIGNMENT-1) );
- if(dtbo_image_buf == (void *)UINT_MAX)
- {
- dprintf(CRITICAL, "ERROR: Invalid DTBO image buf addr\n");
- ret = DTBO_NOT_SUPPORTED;
- goto out;
- }
+ ptn_size = partition_get_size(index);
+ if (ptn_size > MAX_SUPPORTED_DTBO_IMG_BUF)
+ {
+ dprintf(CRITICAL, "ERROR: dtbo parition size is greater than supported.\n");
+ ret = DTBO_ERROR;
+ goto out;
+ }
- /* Read dtbo partition with header */
- if (mmc_read(ptn, (uint32_t *)(dtbo_image_buf), dtbo_partition_size))
- {
- dprintf(CRITICAL, "ERROR: dtbo partition mmc read failure \n");
- ret = DTBO_ERROR;
- goto out;
+ /*
+ Read dtbo image into scratch region after kernel image.
+ dtbo_image_buf_size = total_scratch_region_size - boot_img_sz
+ */
+ boot_img_sz = partition_get_size(partition_get_index("boot"));
+ if (!boot_img_sz)
+ {
+ dprintf(CRITICAL, "ERROR: Unable to get boot partition size\n");
+ ret = DTBO_NOT_SUPPORTED;
+ goto out;
+ }
+
+ dtbo_image_buf_size = target_get_max_flash_size() - boot_img_sz;
+ dtbo_partition_size = ptn_size + ADDR_ALIGNMENT;
+ dtbo_partition_size = ROUND_TO_PAGE(dtbo_partition_size, (page_size - 1)); /* Maximum dtbo size possible */
+ if (dtbo_partition_size == UINT_MAX ||
+ dtbo_image_buf_size < dtbo_partition_size)
+ {
+ dprintf(CRITICAL, "ERROR: Invalid DTBO partition size\n");
+ ret = DTBO_NOT_SUPPORTED;
+ goto out;
+ }
+
+ mmc_set_lun(partition_get_lun(index));
+ /* read dtbo at last 10MB of scratch */
+ dtbo_image_buf = target_get_scratch_address() +
+ (target_get_max_flash_size() - DTBO_IMG_BUF);
+ dtbo_image_buf =
+ (void *)ROUND_TO_PAGE((addr_t)dtbo_image_buf, (ADDR_ALIGNMENT-1) );
+ if(dtbo_image_buf == (void *)UINT_MAX)
+ {
+ dprintf(CRITICAL, "ERROR: Invalid DTBO image buf addr\n");
+ ret = DTBO_NOT_SUPPORTED;
+ goto out;
+ }
+
+ /* Read dtbo partition with header */
+ if (mmc_read(ptn, (uint32_t *)(dtbo_image_buf), dtbo_partition_size))
+ {
+ dprintf(CRITICAL, "ERROR: dtbo partition mmc read failure \n");
+ ret = DTBO_ERROR;
+ goto out;
+ }
}
/* validate the dtbo image, before reading complete image */
diff --git a/platform/msm_shared/include/boot_device.h b/platform/msm_shared/include/boot_device.h
index 4eb172c..2e2a02f 100644
--- a/platform/msm_shared/include/boot_device.h
+++ b/platform/msm_shared/include/boot_device.h
@@ -78,6 +78,7 @@
char *vbcmdline;
uint32_t vbcmdline_len;
uint32_t vbcmdline_filled_len;
+ uint32_t header_version;
void *vb_data;
} bootinfo;
diff --git a/platform/msm_shared/include/dev_tree.h b/platform/msm_shared/include/dev_tree.h
index f6f6003..1d8dd07 100644
--- a/platform/msm_shared/include/dev_tree.h
+++ b/platform/msm_shared/include/dev_tree.h
@@ -60,6 +60,7 @@
#define FOUNDRY_ID_MASK (0x00ff0000)
#define MAX_SUPPORTED_DTBO_IMG_BUF (8388608) /* 8MB 8 * 1024 * 1024 */
#define DTBO_IMG_BUF (10485760) /* 10MB 10 * 1024 * 1024 */
+#define MAX_SUPPORTED_VBMETA_IMG_BUF (65536) /* 64 KB 64 * 1024 */
/*
* For DTB V1: The DTB entries would be of the format
* qcom,msm-id = <msm8974, CDP, rev_1>; (3 * sizeof(uint32_t))
@@ -248,6 +249,7 @@
}dtbo_error;
dtbo_error load_validate_dtbo_image(void **dtbo_img, uint32_t *dtbo_img_size);
+void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf);
int dev_tree_validate(struct dt_table *table, unsigned int page_size, uint32_t *dt_hdr_size);
int dev_tree_get_entry_info(struct dt_table *table, struct dt_entry *dt_entry_info);
int update_device_tree(void *fdt, const char *, void *, unsigned);