app: aboot: Optimize loading flow of bootimage from mmc
Currently we have different loading flow for signed and unsigned
kernel in boot_linux_from_mmc(). However, the main process is
similar. So remove the redundant codes to make the logic more
clear.
Change-Id: I18680a497ac03ce0914853794b65858acb2822d5
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 0bae069..e8021d8 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -865,8 +865,7 @@
uint32_t dt_actual;
uint32_t dt_hdr_size;
#endif
- BUF_DMA_ALIGN(kbuf, BOOT_IMG_MAX_PAGE_SIZE);
- struct kernel64_hdr *kptr = (void*) kbuf;
+ struct kernel64_hdr *kptr = NULL;
if (check_format_bit())
boot_into_recovery = 1;
@@ -927,13 +926,68 @@
page_mask = page_size - 1;
}
- /* Read the next page to get kernel Image header
- * which lives in the second page for arm64 targets.
- */
+ kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
+ ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
- if (mmc_read(ptn + page_size, (uint32_t *) kbuf, page_size)) {
- dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
- return -1;
+ image_addr = (unsigned char *)target_get_scratch_address();
+
+#if DEVICE_TREE
+ dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
+ imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
+#else
+ imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
+#endif
+
+#if VERIFIED_BOOT
+ boot_verifier_init();
+#endif
+
+ if (check_aboot_addr_range_overlap((uint32_t) image_addr, imagesize_actual))
+ {
+ dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
+ return -1;
+ }
+
+ dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
+ bs_set_timestamp(BS_KERNEL_LOAD_START);
+
+ if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
+ {
+ dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
+ return -1;
+ }
+
+ dprintf(INFO, "Loading boot image (%d): done\n", imagesize_actual);
+ bs_set_timestamp(BS_KERNEL_LOAD_DONE);
+
+ /* Authenticate Kernel */
+ dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
+ (int) target_use_signed_kernel(),
+ device.is_unlocked,
+ device.is_tampered);
+
+ if(target_use_signed_kernel() && (!device.is_unlocked))
+ {
+ offset = imagesize_actual;
+ if (check_aboot_addr_range_overlap((uint32_t)image_addr + offset, page_size))
+ {
+ dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
+ return -1;
+ }
+
+ /* Read signature */
+ if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
+ {
+ dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
+ return -1;
+ }
+
+ verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
+ } else {
+ second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
+ #ifdef TZ_SAVE_KERNEL_HASH
+ aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
+ #endif /* TZ_SAVE_KERNEL_HASH */
}
/*
@@ -941,6 +995,7 @@
* has default values, these default values come from mkbootimg when
* the boot image is flashed using fastboot flash:raw
*/
+ kptr = (void *)(image_addr + page_size);
update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
/* Get virtual addresses since the hdr saves physical addresses. */
@@ -948,9 +1003,6 @@
hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
- kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
- ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
-
/* Check if the addresses in the header are valid. */
if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
@@ -967,212 +1019,57 @@
}
#endif
- /* Authenticate Kernel */
- dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
- (int) target_use_signed_kernel(),
- device.is_unlocked,
- device.is_tampered);
-#if VERIFIED_BOOT
- boot_verifier_init();
-#endif
+ /* Move kernel, ramdisk and device tree to correct address */
+ memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
+ memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
- if(target_use_signed_kernel() && (!device.is_unlocked))
- {
- offset = 0;
+ #if DEVICE_TREE
+ if(hdr->dt_size) {
+ dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
+ table = (struct dt_table*) dt_table_offset;
- image_addr = (unsigned char *)target_get_scratch_address();
+ if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
+ dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
+ return -1;
+ }
-#if DEVICE_TREE
- dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
+ /* Find index of device tree within device tree table */
+ if(dev_tree_get_entry_info(table, &dt_entry) != 0){
+ dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
+ return -1;
+ }
- if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_actual))
+ /* Validate and Read device device tree in the tags_addr */
+ if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
{
dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
return -1;
}
-#else
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
-#endif
-
- dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
- bs_set_timestamp(BS_KERNEL_LOAD_START);
-
- if (check_aboot_addr_range_overlap((uint32_t)image_addr, imagesize_actual))
- {
- dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
- return -1;
- }
-
- /* Read image without signature */
- if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
- {
- dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
- return -1;
- }
-
- dprintf(INFO, "Loading boot image (%d): done\n", imagesize_actual);
- bs_set_timestamp(BS_KERNEL_LOAD_DONE);
-
- offset = imagesize_actual;
-
- if (check_aboot_addr_range_overlap((uint32_t)image_addr + offset, page_size))
- {
- dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
- return -1;
- }
-
- /* Read signature */
- if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
- {
- dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
- return -1;
- }
-
- verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
-
- /* Move kernel, ramdisk and device tree to correct address */
- memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
- memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
-
- #if DEVICE_TREE
- if(hdr->dt_size) {
- dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
- table = (struct dt_table*) dt_table_offset;
-
- if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
- dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
- return -1;
- }
-
- /* Find index of device tree within device tree table */
- if(dev_tree_get_entry_info(table, &dt_entry) != 0){
- dprintf(CRITICAL, "ERROR: Device Tree Blob cannot be found\n");
- return -1;
- }
-
- /* Validate and Read device device tree in the "tags_add */
- if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
- {
- dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
- return -1;
- }
-
- memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry.offset, dt_entry.size);
- } else {
- /*
- * If appended dev tree is found, update the atags with
- * memory address to the DTB appended location on RAM.
- * Else update with the atags address in the kernel header
- */
- void *dtb;
- dtb = dev_tree_appended((void*) hdr->kernel_addr,
- hdr->kernel_size,
- (void *)hdr->tags_addr);
- if (!dtb) {
- dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
- return -1;
- }
- }
- #endif
- }
- else
- {
- second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
-
- image_addr = (unsigned char *)target_get_scratch_address();
-#if DEVICE_TREE
- dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
-
- if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_actual))
+ memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry.offset, dt_entry.size);
+ } else {
+ /* Validate the tags_addr */
+ if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
{
dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
return -1;
}
-#else
- imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
-
-#endif
- if (check_aboot_addr_range_overlap((uint32_t) image_addr, imagesize_actual))
- {
- dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
+ /*
+ * If appended dev tree is found, update the atags with
+ * memory address to the DTB appended location on RAM.
+ * Else update with the atags address in the kernel header
+ */
+ void *dtb;
+ dtb = dev_tree_appended((void*) hdr->kernel_addr,
+ kernel_actual,
+ (void *)hdr->tags_addr);
+ if (!dtb) {
+ dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
return -1;
}
-
- dprintf(INFO, "Loading boot image (%d): start\n",
- imagesize_actual);
- bs_set_timestamp(BS_KERNEL_LOAD_START);
-
- offset = 0;
-
- /* Load the entire boot image */
- if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual)) {
- dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
- return -1;
- }
-
- dprintf(INFO, "Loading boot image (%d): done\n",
- imagesize_actual);
- bs_set_timestamp(BS_KERNEL_LOAD_DONE);
-
- #ifdef TZ_SAVE_KERNEL_HASH
- aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
- #endif /* TZ_SAVE_KERNEL_HASH */
-
- /* Move kernel, ramdisk and device tree to correct address */
- memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
- memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
-
- #if DEVICE_TREE
- if(hdr->dt_size) {
- dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
- table = (struct dt_table*) dt_table_offset;
-
- if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
- dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
- return -1;
- }
-
- /* Find index of device tree within device tree table */
- if(dev_tree_get_entry_info(table, &dt_entry) != 0){
- dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
- return -1;
- }
-
- /* Validate and Read device device tree in the tags_addr */
- if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
- {
- dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
- return -1;
- }
-
- memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry.offset, dt_entry.size);
- } else {
- /* Validate the tags_addr */
- if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
- {
- dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
- return -1;
- }
- /*
- * If appended dev tree is found, update the atags with
- * memory address to the DTB appended location on RAM.
- * Else update with the atags address in the kernel header
- */
- void *dtb;
- dtb = dev_tree_appended((void*) hdr->kernel_addr,
- kernel_actual,
- (void *)hdr->tags_addr);
- if (!dtb) {
- dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
- return -1;
- }
- }
- #endif
}
+ #endif
if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
target_load_ssd_keystore();