diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/aboot.c | 2438 |
1 files changed, 0 insertions, 2438 deletions
diff --git a/common/aboot.c b/common/aboot.c index 3b5092d..a302c92 100644 --- a/common/aboot.c +++ b/common/aboot.c @@ -30,1819 +30,6 @@ * */ -#include <app.h> -#include <debug.h> -#include <arch/arm.h> -#include <string.h> -#include <stdlib.h> -#include <limits.h> -#include <kernel/thread.h> -#include <arch/ops.h> - -#include <dev/flash.h> -#include <lib/ptable.h> -#include <dev/keys.h> -#include <dev/fbcon.h> -#include <baseband.h> -#include <target.h> -#include <mmc.h> -#include <partition_parser.h> -#include <platform.h> -#include <crypto_hash.h> -#include <malloc.h> -#include <boot_stats.h> -#include <sha.h> -#include <platform/iomap.h> -#include <boot_device.h> - -#if DEVICE_TREE -#include <libfdt.h> -#include <dev_tree.h> -#endif - -#include "image_verify.h" -#include "recovery.h" -#include "bootimg.h" -#include "fastboot.h" -#include "sparse_format.h" -#include "mmc.h" -#include "devinfo.h" -#include "board.h" -#include "scm.h" - -extern bool target_use_signed_kernel(void); -extern void platform_uninit(void); -extern void target_uninit(void); -extern int get_target_boot_params(const char *cmdline, const char *part, - char *buf, int buflen); - -void write_device_info_mmc(device_info *dev); -void write_device_info_flash(device_info *dev); - -#define EXPAND(NAME) #NAME -#define TARGET(NAME) EXPAND(NAME) - -#ifdef MEMBASE -#define EMMC_BOOT_IMG_HEADER_ADDR (0xFF000+(MEMBASE)) -#else -#define EMMC_BOOT_IMG_HEADER_ADDR 0xFF000 -#endif - -#ifndef MEMSIZE -#define MEMSIZE 1024*1024 -#endif - -#define MAX_TAGS_SIZE 1024 - -#define RECOVERY_MODE 0x77665502 -#define FASTBOOT_MODE 0x77665500 - -/* make 4096 as default size to ensure EFS,EXT4's erasing */ -#define DEFAULT_ERASE_SIZE 4096 -#define MAX_PANEL_BUF_SIZE 128 - -#define UBI_MAGIC "UBI#" -#define DISPLAY_DEFAULT_PREFIX "mdss_mdp" -#define UBI_MAGIC_SIZE 0x04 -#define BOOT_DEV_MAX_LEN 64 - -#define IS_ARM64(ptr) (ptr->magic_64 == KERNEL64_HDR_MAGIC) ? true : false - -#define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX - -#if UFS_SUPPORT -static const char *emmc_cmdline = " androidboot.bootdevice="; -#else -static const char *emmc_cmdline = " androidboot.emmc=true"; -#endif -static const char *usb_sn_cmdline = " androidboot.serialno="; -static const char *androidboot_mode = " androidboot.mode="; -static const char *loglevel = " quiet"; -static const char *battchg_pause = " androidboot.mode=charger"; -static const char *auth_kernel = " androidboot.authorized_kernel=true"; -static const char *secondary_gpt_enable = " gpt"; - -static const char *baseband_apq = " androidboot.baseband=apq"; -static const char *baseband_msm = " androidboot.baseband=msm"; -static const char *baseband_csfb = " androidboot.baseband=csfb"; -static const char *baseband_svlte2a = " androidboot.baseband=svlte2a"; -static const char *baseband_mdm = " androidboot.baseband=mdm"; -static const char *baseband_mdm2 = " androidboot.baseband=mdm2"; -static const char *baseband_sglte = " androidboot.baseband=sglte"; -static const char *baseband_dsda = " androidboot.baseband=dsda"; -static const char *baseband_dsda2 = " androidboot.baseband=dsda2"; -static const char *baseband_sglte2 = " androidboot.baseband=sglte2"; -static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1"; - -static unsigned page_size = 0; -static unsigned page_mask = 0; -static char ffbm_mode_string[FFBM_MODE_BUF_SIZE]; -static bool boot_into_ffbm; -static char target_boot_params[64]; - -/* Assuming unauthorized kernel image by default */ -static int auth_kernel_img = 0; - -static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0}; - -struct atag_ptbl_entry -{ - char name[16]; - unsigned offset; - unsigned size; - unsigned flags; -}; - -/* - * Partition info, required to be published - * for fastboot - */ -struct getvar_partition_info { - const char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */ - char getvar_size[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for size */ - char getvar_type[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for type */ - char size_response[MAX_RSP_SIZE]; /* fastboot response for size */ - char type_response[MAX_RSP_SIZE]; /* fastboot response for type */ -}; - -/* - * Right now, we are publishing the info for only - * three partitions - */ -struct getvar_partition_info part_info[] = -{ - { "system" , "partition-size:", "partition-type:", "", "ext4" }, - { "userdata", "partition-size:", "partition-type:", "", "ext4" }, - { "cache" , "partition-size:", "partition-type:", "", "ext4" }, -}; - -char max_download_size[MAX_RSP_SIZE]; -char charger_screen_enabled[MAX_RSP_SIZE]; -char sn_buf[13]; -char display_panel_buf[MAX_PANEL_BUF_SIZE]; -char panel_display_mode[MAX_RSP_SIZE]; - -extern int emmc_recovery_init(void); - -#if NO_KEYPAD_DRIVER -extern int fastboot_trigger(void); -#endif - -static void update_ker_tags_rdisk_addr(struct boot_img_hdr *hdr, bool is_arm64) -{ - /* overwrite the destination of specified for the project */ -#ifdef ABOOT_IGNORE_BOOT_HEADER_ADDRS - if (is_arm64) - hdr->kernel_addr = ABOOT_FORCE_KERNEL64_ADDR; - else - hdr->kernel_addr = ABOOT_FORCE_KERNEL_ADDR; - hdr->ramdisk_addr = ABOOT_FORCE_RAMDISK_ADDR; - hdr->tags_addr = ABOOT_FORCE_TAGS_ADDR; -#endif -} - -static void ptentry_to_tag(unsigned **ptr, struct ptentry *ptn) -{ - struct atag_ptbl_entry atag_ptn; - - memcpy(atag_ptn.name, ptn->name, 16); - atag_ptn.name[15] = '\0'; - atag_ptn.offset = ptn->start; - atag_ptn.size = ptn->length; - atag_ptn.flags = ptn->flags; - memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry)); - *ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned); -} - -unsigned char *update_cmdline(const char * cmdline) -{ - int cmdline_len = 0; - int have_cmdline = 0; - unsigned char *cmdline_final = NULL; - int pause_at_bootup = 0; - bool warm_boot = false; - bool gpt_exists = partition_gpt_exists(); - int have_target_boot_params = 0; - char *boot_dev_buf = NULL; - - if (cmdline && cmdline[0]) { - cmdline_len = strlen(cmdline); - have_cmdline = 1; - } - if (target_is_emmc_boot()) { - cmdline_len += strlen(emmc_cmdline); -#if UFS_SUPPORT - boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN); - ASSERT(boot_dev_buf); - platform_boot_dev_cmdline(boot_dev_buf); - cmdline_len += strlen(boot_dev_buf); -#endif - } - - cmdline_len += strlen(usb_sn_cmdline); - cmdline_len += strlen(sn_buf); - - if (boot_into_recovery && gpt_exists) - cmdline_len += strlen(secondary_gpt_enable); - - if (boot_into_ffbm) { - cmdline_len += strlen(androidboot_mode); - cmdline_len += strlen(ffbm_mode_string); - /* reduce kernel console messages to speed-up boot */ - cmdline_len += strlen(loglevel); - } else if (device.charger_screen_enabled && - target_pause_for_battery_charge()) { - pause_at_bootup = 1; - cmdline_len += strlen(battchg_pause); - } - - if(target_use_signed_kernel() && auth_kernel_img) { - cmdline_len += strlen(auth_kernel); - } - - if (get_target_boot_params(cmdline, boot_into_recovery ? "recoveryfs" : - "system", - target_boot_params, - sizeof(target_boot_params)) == 0) { - have_target_boot_params = 1; - cmdline_len += strlen(target_boot_params); - } - - /* Determine correct androidboot.baseband to use */ - switch(target_baseband()) - { - case BASEBAND_APQ: - cmdline_len += strlen(baseband_apq); - break; - - case BASEBAND_MSM: - cmdline_len += strlen(baseband_msm); - break; - - case BASEBAND_CSFB: - cmdline_len += strlen(baseband_csfb); - break; - - case BASEBAND_SVLTE2A: - cmdline_len += strlen(baseband_svlte2a); - break; - - case BASEBAND_MDM: - cmdline_len += strlen(baseband_mdm); - break; - - case BASEBAND_MDM2: - cmdline_len += strlen(baseband_mdm2); - break; - - case BASEBAND_SGLTE: - cmdline_len += strlen(baseband_sglte); - break; - - case BASEBAND_SGLTE2: - cmdline_len += strlen(baseband_sglte2); - break; - - case BASEBAND_DSDA: - cmdline_len += strlen(baseband_dsda); - break; - - case BASEBAND_DSDA2: - cmdline_len += strlen(baseband_dsda2); - break; - } - - if (cmdline) { - if ((strstr(cmdline, DISPLAY_DEFAULT_PREFIX) == NULL) && - target_display_panel_node(device.display_panel, - display_panel_buf, MAX_PANEL_BUF_SIZE) && - strlen(display_panel_buf)) { - cmdline_len += strlen(display_panel_buf); - } - } - - if (target_warm_boot()) { - warm_boot = true; - cmdline_len += strlen(warmboot_cmdline); - } - - if (cmdline_len > 0) { - const char *src; - unsigned char *dst = (unsigned char*) malloc((cmdline_len + 4) & (~3)); - ASSERT(dst != NULL); - - /* Save start ptr for debug print */ - cmdline_final = dst; - if (have_cmdline) { - src = cmdline; - while ((*dst++ = *src++)); - } - if (target_is_emmc_boot()) { - src = emmc_cmdline; - if (have_cmdline) --dst; - have_cmdline = 1; - while ((*dst++ = *src++)); -#if UFS_SUPPORT - src = boot_dev_buf; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); -#endif - } - - src = usb_sn_cmdline; - if (have_cmdline) --dst; - have_cmdline = 1; - while ((*dst++ = *src++)); - src = sn_buf; - if (have_cmdline) --dst; - have_cmdline = 1; - while ((*dst++ = *src++)); - if (warm_boot) { - if (have_cmdline) --dst; - src = warmboot_cmdline; - while ((*dst++ = *src++)); - } - - if (boot_into_recovery && gpt_exists) { - src = secondary_gpt_enable; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - } - - if (boot_into_ffbm) { - src = androidboot_mode; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - src = ffbm_mode_string; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - src = loglevel; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - } else if (pause_at_bootup) { - src = battchg_pause; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - } - - if(target_use_signed_kernel() && auth_kernel_img) { - src = auth_kernel; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - } - - switch(target_baseband()) - { - case BASEBAND_APQ: - src = baseband_apq; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_MSM: - src = baseband_msm; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_CSFB: - src = baseband_csfb; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_SVLTE2A: - src = baseband_svlte2a; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_MDM: - src = baseband_mdm; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_MDM2: - src = baseband_mdm2; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_SGLTE: - src = baseband_sglte; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_SGLTE2: - src = baseband_sglte2; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_DSDA: - src = baseband_dsda; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - - case BASEBAND_DSDA2: - src = baseband_dsda2; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - break; - } - - if (strlen(display_panel_buf)) { - src = display_panel_buf; - if (have_cmdline) --dst; - while ((*dst++ = *src++)); - } - - if (have_target_boot_params) { - if (have_cmdline) --dst; - src = target_boot_params; - while ((*dst++ = *src++)); - } - } - - - if (boot_dev_buf) - free(boot_dev_buf); - - dprintf(INFO, "cmdline: %s\n", cmdline_final); - return cmdline_final; -} - -unsigned *atag_core(unsigned *ptr) -{ - /* CORE */ - *ptr++ = 2; - *ptr++ = 0x54410001; - - return ptr; - -} - -unsigned *atag_ramdisk(unsigned *ptr, void *ramdisk, - unsigned ramdisk_size) -{ - if (ramdisk_size) { - *ptr++ = 4; - *ptr++ = 0x54420005; - *ptr++ = (unsigned)ramdisk; - *ptr++ = ramdisk_size; - } - - return ptr; -} - -unsigned *atag_ptable(unsigned **ptr_addr) -{ - int i; - struct ptable *ptable; - - if ((ptable = flash_get_ptable()) && (ptable->count != 0)) { - *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) / - sizeof(unsigned))); - *(*ptr_addr)++ = 0x4d534d70; - for (i = 0; i < ptable->count; ++i) - ptentry_to_tag(ptr_addr, ptable_get(ptable, i)); - } - - return (*ptr_addr); -} - -unsigned *atag_cmdline(unsigned *ptr, const char *cmdline) -{ - int cmdline_length = 0; - int n; - char *dest; - - cmdline_length = strlen((const char*)cmdline); - n = (cmdline_length + 4) & (~3); - - *ptr++ = (n / 4) + 2; - *ptr++ = 0x54410009; - dest = (char *) ptr; - while ((*dest++ = *cmdline++)); - ptr += (n / 4); - - return ptr; -} - -unsigned *atag_end(unsigned *ptr) -{ - /* END */ - *ptr++ = 0; - *ptr++ = 0; - - return ptr; -} - -void generate_atags(unsigned *ptr, const char *cmdline, - void *ramdisk, unsigned ramdisk_size) -{ - - ptr = atag_core(ptr); - ptr = atag_ramdisk(ptr, ramdisk, ramdisk_size); - ptr = target_atag_mem(ptr); - - /* Skip NAND partition ATAGS for eMMC boot */ - if (!target_is_emmc_boot()){ - ptr = atag_ptable(&ptr); - } - - ptr = atag_cmdline(ptr, cmdline); - ptr = atag_end(ptr); -} - -typedef void entry_func_ptr(unsigned, unsigned, unsigned*); -void boot_linux(void *kernel, unsigned *tags, - const char *cmdline, unsigned machtype, - void *ramdisk, unsigned ramdisk_size) -{ - unsigned char *final_cmdline; -#if DEVICE_TREE - int ret = 0; -#endif - - void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel)); - uint32_t tags_phys = PA((addr_t)tags); - struct kernel64_hdr *kptr = (struct kernel64_hdr*)kernel; - - ramdisk = PA(ramdisk); - - final_cmdline = update_cmdline((const char*)cmdline); - -#if DEVICE_TREE - dprintf(INFO, "Updating device tree: start\n"); - - /* Update the Device Tree */ - ret = update_device_tree((void *)tags, final_cmdline, ramdisk, ramdisk_size); - if(ret) - { - dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n"); - ASSERT(0); - } - dprintf(INFO, "Updating device tree: done\n"); -#else - /* Generating the Atags */ - generate_atags(tags, final_cmdline, ramdisk, ramdisk_size); -#endif - - /* Perform target specific cleanup */ - target_uninit(); - - /* Turn off splash screen if enabled */ -#if DISPLAY_SPLASH_SCREEN - target_display_shutdown(); -#endif - - - dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d), tags/device tree @ %p\n", - entry, ramdisk, ramdisk_size, tags_phys); - - enter_critical_section(); - - /* do any platform specific cleanup before kernel entry */ - platform_uninit(); - - arch_disable_cache(UCACHE); - -#if ARM_WITH_MMU - arch_disable_mmu(); -#endif - bs_set_timestamp(BS_KERNEL_ENTRY); - - if (IS_ARM64(kptr)) - /* Jump to a 64bit kernel */ - scm_elexec_call((paddr_t)kernel, tags_phys); - else - /* Jump to a 32bit kernel */ - entry(0, machtype, (unsigned*)tags_phys); -} - -/* Function to check if the memory address range falls within the aboot - * boundaries. - * start: Start of the memory region - * size: Size of the memory region - */ -int check_aboot_addr_range_overlap(uint32_t start, uint32_t size) -{ - /* Check for boundary conditions. */ - if ((UINT_MAX - start) < size) - return -1; - - /* Check for memory overlap. */ - if ((start < MEMBASE) && ((start + size) <= MEMBASE)) - return 0; - else if (start >= (MEMBASE + MEMSIZE)) - return 0; - else - return -1; -} - -#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y))) - -BUF_DMA_ALIGN(buf, BOOT_IMG_MAX_PAGE_SIZE); //Equal to max-supported pagesize -#if DEVICE_TREE -BUF_DMA_ALIGN(dt_buf, BOOT_IMG_MAX_PAGE_SIZE); -#endif - -static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size) -{ - int ret; -#if IMAGE_VERIF_ALGO_SHA1 - uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1; -#else - uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256; -#endif - - /* Assume device is rooted at this time. */ - device.is_tampered = 1; - - dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size); - - ret = image_verify((unsigned char *)bootimg_addr, - (unsigned char *)(bootimg_addr + bootimg_size), - bootimg_size, - auth_algo); - - dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret); - - if (ret) - { - /* Authorized kernel */ - device.is_tampered = 0; - auth_kernel_img = 1; - } - -#if USE_PCOM_SECBOOT - set_tamper_flag(device.is_tampered); -#endif - - if(device.is_tampered) - { - write_device_info_mmc(&device); - #ifdef TZ_TAMPER_FUSE - set_tamper_fuse_cmd(); - #endif - #ifdef ASSERT_ON_TAMPER - dprintf(CRITICAL, "Device is tampered. Asserting..\n"); - ASSERT(0); - #endif - } -} - -static bool check_format_bit() -{ - bool ret = false; - int index; - uint64_t offset; - struct boot_selection_info *in = NULL; - char *buf = NULL; - - index = partition_get_index("bootselect"); - if (index == INVALID_PTN) - { - dprintf(INFO, "Unable to locate /bootselect partition\n"); - return ret; - } - offset = partition_get_offset(index); - if(!offset) - { - dprintf(INFO, "partition /bootselect doesn't exist\n"); - return ret; - } - buf = (char *) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE)); - ASSERT(buf); - if (mmc_read(offset, (unsigned int *)buf, page_size)) - { - dprintf(INFO, "mmc read failure /bootselect %d\n", page_size); - free(buf); - return ret; - } - in = (struct boot_selection_info *) buf; - if ((in->signature == BOOTSELECT_SIGNATURE) && - (in->version == BOOTSELECT_VERSION)) { - if ((in->state_info & BOOTSELECT_FORMAT) && - !(in->state_info & BOOTSELECT_FACTORY)) - ret = true; - } else { - dprintf(CRITICAL, "Signature: 0x%08x or version: 0x%08x mismatched of /bootselect\n", - in->signature, in->version); - ASSERT(0); - } - free(buf); - return ret; -} - -int boot_linux_from_mmc(void) -{ - struct boot_img_hdr *hdr = (void*) buf; - struct boot_img_hdr *uhdr; - unsigned offset = 0; - int rcode; - unsigned long long ptn = 0; - int index = INVALID_PTN; - - unsigned char *image_addr = 0; - unsigned kernel_actual; - unsigned ramdisk_actual; - unsigned imagesize_actual; - unsigned second_actual = 0; - -#if DEVICE_TREE - struct dt_table *table; - struct dt_entry dt_entry; - unsigned dt_table_offset; - 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; - - if (check_format_bit()) - boot_into_recovery = 1; - - if (!boot_into_recovery) { - memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string)); - rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string)); - if (rcode <= 0) { - boot_into_ffbm = false; - if (rcode < 0) - dprintf(CRITICAL,"failed to get ffbm cookie"); - } else - boot_into_ffbm = true; - } else - boot_into_ffbm = false; - uhdr = (struct 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; - goto unified_boot; - } - if (!boot_into_recovery) { - index = partition_get_index("boot"); - ptn = partition_get_offset(index); - if(ptn == 0) { - dprintf(CRITICAL, "ERROR: No boot partition found\n"); - return -1; - } - } - else { - index = partition_get_index("recovery"); - ptn = partition_get_offset(index); - if(ptn == 0) { - dprintf(CRITICAL, "ERROR: No recovery partition found\n"); - return -1; - } - } - - if (mmc_read(ptn + offset, (unsigned int *) buf, page_size)) { - dprintf(CRITICAL, "ERROR: Cannot read boot image header\n"); - return -1; - } - - if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { - dprintf(CRITICAL, "ERROR: Invalid boot image header\n"); - return -1; - } - - if (hdr->page_size && (hdr->page_size != page_size)) { - - if (hdr->page_size > BOOT_IMG_MAX_PAGE_SIZE) { - dprintf(CRITICAL, "ERROR: Invalid page size\n"); - return -1; - } - page_size = hdr->page_size; - page_mask = page_size - 1; - } - - /* Read the next page to get kernel Image header - * which lives in the second page for arm64 targets. - */ - - if (mmc_read(ptn + page_size, (unsigned int *) kbuf, page_size)) { - dprintf(CRITICAL, "ERROR: Cannot read boot image header\n"); - return -1; - } - - /* - * Update the kernel/ramdisk/tags address if the boot image header - * has default values, these default values come from mkbootimg when - * the boot image is flashed using fastboot flash:raw - */ - update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr)); - - /* Get virtual addresses since the hdr saves physical addresses. */ - hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr)); - 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)) - { - dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n"); - return -1; - } - -#ifndef DEVICE_TREE - if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE)) - { - dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n"); - return -1; - } -#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(target_use_signed_kernel() && (!device.is_unlocked)) - { - offset = 0; - - 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)) - { - 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(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(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(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); - - dprintf(INFO, "Loading boot image (%d): start\n", - kernel_actual + ramdisk_actual); - bs_set_timestamp(BS_KERNEL_LOAD_START); - - offset = page_size; - - /* Load kernel */ - if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, kernel_actual)) { - dprintf(CRITICAL, "ERROR: Cannot read kernel image\n"); - return -1; - } - offset += kernel_actual; - - /* Load ramdisk */ - if(ramdisk_actual != 0) - { - if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, ramdisk_actual)) { - dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n"); - return -1; - } - } - offset += ramdisk_actual; - - dprintf(INFO, "Loading boot image (%d): done\n", - kernel_actual + ramdisk_actual); - bs_set_timestamp(BS_KERNEL_LOAD_DONE); - - if(hdr->second_size != 0) { - offset += second_actual; - /* Second image loading not implemented. */ - ASSERT(0); - } - - #if DEVICE_TREE - if(hdr->dt_size != 0) { - /* Read the first page of device tree table into buffer */ - if(mmc_read(ptn + offset,(unsigned int *) dt_buf, page_size)) { - dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n"); - return -1; - } - table = (struct dt_table*) dt_buf; - - if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) { - dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n"); - return -1; - } - - table = (struct dt_table*) memalign(CACHE_LINE, dt_hdr_size); - if (!table) - return -1; - - /* Read the entire device tree table into buffer */ - if(mmc_read(ptn + offset,(unsigned int *) table, dt_hdr_size)) { - dprintf(CRITICAL, "ERROR: Cannot read the 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_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; - } - - if(mmc_read(ptn + offset + dt_entry.offset, - (void *)hdr->tags_addr, dt_entry.size)) { - dprintf(CRITICAL, "ERROR: Cannot read device tree\n"); - return -1; - } - #ifdef TZ_SAVE_KERNEL_HASH - aboot_save_boot_hash_mmc(hdr->kernel_addr, kernel_actual, - hdr->ramdisk_addr, ramdisk_actual, - ptn, offset, hdr->dt_size); - #endif /* TZ_SAVE_KERNEL_HASH */ - - } 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 - } - - if (boot_into_recovery && !device.is_unlocked && !device.is_tampered) - target_load_ssd_keystore(); - -unified_boot: - - boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr, - (const char *)hdr->cmdline, board_machtype(), - (void *)hdr->ramdisk_addr, hdr->ramdisk_size); - - return 0; -} - -int boot_linux_from_flash(void) -{ - struct boot_img_hdr *hdr = (void*) buf; - struct ptentry *ptn; - struct ptable *ptable; - unsigned offset = 0; - - unsigned char *image_addr = 0; - unsigned kernel_actual; - unsigned ramdisk_actual; - unsigned imagesize_actual; - unsigned second_actual; - -#if DEVICE_TREE - struct dt_table *table; - struct dt_entry dt_entry; - uint32_t dt_actual; - uint32_t dt_hdr_size; -#endif - - if (target_is_emmc_boot()) { - hdr = (struct 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; - } - goto continue_boot; - } - - ptable = flash_get_ptable(); - if (ptable == NULL) { - dprintf(CRITICAL, "ERROR: Partition table not found\n"); - return -1; - } - - if(!boot_into_recovery) - { - ptn = ptable_find(ptable, "boot"); - - if (ptn == NULL) { - dprintf(CRITICAL, "ERROR: No boot partition found\n"); - return -1; - } - } - else - { - ptn = ptable_find(ptable, "recovery"); - if (ptn == NULL) { - dprintf(CRITICAL, "ERROR: No recovery partition found\n"); - return -1; - } - } - - if (flash_read(ptn, offset, buf, page_size)) { - dprintf(CRITICAL, "ERROR: Cannot read boot image header\n"); - return -1; - } - - if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { - dprintf(CRITICAL, "ERROR: Invalid boot image header\n"); - return -1; - } - - if (hdr->page_size != page_size) { - dprintf(CRITICAL, "ERROR: Invalid boot image pagesize. Device pagesize: %d, Image pagesize: %d\n",page_size,hdr->page_size); - return -1; - } - - /* - * Update the kernel/ramdisk/tags address if the boot image header - * has default values, these default values come from mkbootimg when - * the boot image is flashed using fastboot flash:raw - */ - update_ker_tags_rdisk_addr(hdr, false); - - /* Get virtual addresses since the hdr saves physical addresses. */ - hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr)); - 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)) - { - dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n"); - return -1; - } - -#ifndef DEVICE_TREE - if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE)) - { - dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n"); - return -1; - } -#endif - - /* Authenticate Kernel */ - if(target_use_signed_kernel() && (!device.is_unlocked)) - { - image_addr = (unsigned char *)target_get_scratch_address(); - offset = 0; - -#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, hdr->dt_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); - - /* Read image without signature */ - if (flash_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; - /* Read signature */ - if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size)) - { - dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n"); - return -1; - } - - verify_signed_bootimg(image_addr, imagesize_actual); - - /* Move kernel and ramdisk 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 - /* 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 *)(image_addr + page_size + kernel_actual + ramdisk_actual), hdr->dt_size); -#endif - - /* Make sure everything from scratch address is read before next step!*/ - if(device.is_tampered) - { - write_device_info_flash(&device); - } -#if USE_PCOM_SECBOOT - set_tamper_flag(device.is_tampered); -#endif - } - else - { - offset = page_size; - - kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask); - ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); - second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask); - - dprintf(INFO, "Loading boot image (%d): start\n", - kernel_actual + ramdisk_actual); - bs_set_timestamp(BS_KERNEL_LOAD_START); - - if (flash_read(ptn, offset, (void *)hdr->kernel_addr, kernel_actual)) { - dprintf(CRITICAL, "ERROR: Cannot read kernel image\n"); - return -1; - } - offset += kernel_actual; - - if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, ramdisk_actual)) { - dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n"); - return -1; - } - offset += ramdisk_actual; - - dprintf(INFO, "Loading boot image (%d): done\n", - kernel_actual + ramdisk_actual); - bs_set_timestamp(BS_KERNEL_LOAD_DONE); - - if(hdr->second_size != 0) { - offset += second_actual; - /* Second image loading not implemented. */ - ASSERT(0); - } - -#if DEVICE_TREE - if(hdr->dt_size != 0) { - - /* Read the device tree table into buffer */ - if(flash_read(ptn, offset, (void *) dt_buf, page_size)) { - dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n"); - return -1; - } - - table = (struct dt_table*) dt_buf; - - if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) { - dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n"); - return -1; - } - - table = (struct dt_table*) memalign(CACHE_LINE, dt_hdr_size); - if (!table) - return -1; - - /* Read the entire device tree table into buffer */ - if(flash_read(ptn, offset, (void *)table, dt_hdr_size)) { - dprintf(CRITICAL, "ERROR: Cannot read the 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_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; - } - - /* Read device device tree in the "tags_add */ - if(flash_read(ptn, offset + dt_entry.offset, - (void *)hdr->tags_addr, dt_entry.size)) { - dprintf(CRITICAL, "ERROR: Cannot read device tree\n"); - return -1; - } - } -#endif - - } -continue_boot: - - /* TODO: create/pass atags to kernel */ - - boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr, - (const char *)hdr->cmdline, board_machtype(), - (void *)hdr->ramdisk_addr, hdr->ramdisk_size); - - return 0; -} - -BUF_DMA_ALIGN(info_buf, BOOT_IMG_MAX_PAGE_SIZE); -void write_device_info_mmc(device_info *dev) -{ - struct device_info *info = (void*) info_buf; - unsigned long long ptn = 0; - unsigned long long size; - int index = INVALID_PTN; - uint32_t blocksize; - uint8_t lun = 0; - - index = partition_get_index("aboot"); - ptn = partition_get_offset(index); - if(ptn == 0) - { - return; - } - - lun = partition_get_lun(index); - mmc_set_lun(lun); - - size = partition_get_size(index); - - memcpy(info, dev, sizeof(device_info)); - - blocksize = mmc_get_device_blocksize(); - - if(mmc_write((ptn + size - blocksize), blocksize, (void *)info_buf)) - { - dprintf(CRITICAL, "ERROR: Cannot write device info\n"); - return; - } -} - -void read_device_info_mmc(device_info *dev) -{ - struct device_info *info = (void*) info_buf; - unsigned long long ptn = 0; - unsigned long long size; - int index = INVALID_PTN; - uint32_t blocksize; - - index = partition_get_index("aboot"); - ptn = partition_get_offset(index); - if(ptn == 0) - { - return; - } - - size = partition_get_size(index); - - blocksize = mmc_get_device_blocksize(); - - if(mmc_read((ptn + size - blocksize), (void *)info_buf, blocksize)) - { - dprintf(CRITICAL, "ERROR: Cannot read device info\n"); - return; - } - - if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE)) - { - memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE); - info->is_unlocked = 0; - info->is_tampered = 0; - info->charger_screen_enabled = 0; - - write_device_info_mmc(info); - } - memcpy(dev, info, sizeof(device_info)); -} - -void write_device_info_flash(device_info *dev) -{ - struct device_info *info = (void *) info_buf; - struct ptentry *ptn; - struct ptable *ptable; - - ptable = flash_get_ptable(); - if (ptable == NULL) - { - dprintf(CRITICAL, "ERROR: Partition table not found\n"); - return; - } - - ptn = ptable_find(ptable, "devinfo"); - if (ptn == NULL) - { - dprintf(CRITICAL, "ERROR: No boot partition found\n"); - return; - } - - memcpy(info, dev, sizeof(device_info)); - - if (flash_write(ptn, 0, (void *)info_buf, page_size)) - { - dprintf(CRITICAL, "ERROR: Cannot write device info\n"); - return; - } -} - -void read_device_info_flash(device_info *dev) -{ - struct device_info *info = (void*) info_buf; - struct ptentry *ptn; - struct ptable *ptable; - - ptable = flash_get_ptable(); - if (ptable == NULL) - { - dprintf(CRITICAL, "ERROR: Partition table not found\n"); - return; - } - - ptn = ptable_find(ptable, "devinfo"); - if (ptn == NULL) - { - dprintf(CRITICAL, "ERROR: No boot partition found\n"); - return; - } - - if (flash_read(ptn, 0, (void *)info_buf, page_size)) - { - dprintf(CRITICAL, "ERROR: Cannot write device info\n"); - return; - } - - if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE)) - { - memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE); - info->is_unlocked = 0; - info->is_tampered = 0; - write_device_info_flash(info); - } - memcpy(dev, info, sizeof(device_info)); -} - -void write_device_info(device_info *dev) -{ - if(target_is_emmc_boot()) - { - write_device_info_mmc(dev); - } - else - { - write_device_info_flash(dev); - } -} - -void read_device_info(device_info *dev) -{ - if(target_is_emmc_boot()) - { - read_device_info_mmc(dev); - } - else - { - read_device_info_flash(dev); - } -} - -void reset_device_info() -{ - dprintf(ALWAYS, "reset_device_info called."); - device.is_tampered = 0; - write_device_info(&device); -} - -void set_device_root() -{ - dprintf(ALWAYS, "set_device_root called."); - device.is_tampered = 1; - write_device_info(&device); -} - -#if DEVICE_TREE -int copy_dtb(uint8_t *boot_image_start) -{ - uint32 dt_image_offset = 0; - uint32_t n; - struct dt_table *table; - struct dt_entry dt_entry; - uint32_t dt_hdr_size; - - struct boot_img_hdr *hdr = (struct boot_img_hdr *) (boot_image_start); - - if(hdr->dt_size != 0) { - - /* add kernel offset */ - dt_image_offset += page_size; - n = ROUND_TO_PAGE(hdr->kernel_size, page_mask); - dt_image_offset += n; - - /* add ramdisk offset */ - n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); - dt_image_offset += n; - - /* add second offset */ - if(hdr->second_size != 0) { - n = ROUND_TO_PAGE(hdr->second_size, page_mask); - dt_image_offset += n; - } - - /* offset now point to start of dt.img */ - table = (struct dt_table*)(boot_image_start + dt_image_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_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; - } - - /* Read device device tree in the "tags_add */ - memmove((void*) hdr->tags_addr, - boot_image_start + dt_image_offset + dt_entry.offset, - dt_entry.size); - } else - return -1; - - /* Everything looks fine. Return success. */ - return 0; -} -#endif - -void cmd_boot(const char *arg, void *data, unsigned sz) -{ - unsigned kernel_actual; - unsigned ramdisk_actual; - uint32_t image_actual; - uint32_t dt_actual = 0; - uint32_t sig_actual = SIGNATURE_SIZE; - struct boot_img_hdr *hdr; - struct kernel64_hdr *kptr; - char *ptr = ((char*) data); - int ret = 0; - uint8_t dtb_copied = 0; - - if (sz < sizeof(hdr)) { - fastboot_fail("invalid bootimage header"); - return; - } - - hdr = (struct boot_img_hdr *)data; - - /* ensure commandline is terminated */ - hdr->cmdline[BOOT_ARGS_SIZE-1] = 0; - - if(target_is_emmc_boot() && hdr->page_size) { - page_size = hdr->page_size; - page_mask = page_size - 1; - } - - kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask); - ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); -#if DEVICE_TREE - dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask); -#endif - - image_actual = ADD_OF(page_size, kernel_actual); - image_actual = ADD_OF(image_actual, ramdisk_actual); - image_actual = ADD_OF(image_actual, dt_actual); - - if (target_use_signed_kernel() && (!device.is_unlocked)) - image_actual = ADD_OF(image_actual, sig_actual); - - /* sz should have atleast raw boot image */ - if (image_actual > sz) { - fastboot_fail("bootimage: incomplete or not signed"); - return; - } - - /* Verify the boot image - * device & page_size are initialized in aboot_init - */ - if (target_use_signed_kernel() && (!device.is_unlocked)) - /* Pass size excluding signature size, otherwise we would try to - * access signature beyond its length - */ - verify_signed_bootimg((uint32_t)data, (image_actual - sig_actual)); - - /* - * Update the kernel/ramdisk/tags address if the boot image header - * has default values, these default values come from mkbootimg when - * the boot image is flashed using fastboot flash:raw - */ - kptr = (struct kernel64_hdr*)((char*) data + page_size); - update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr)); - - /* Get virtual addresses since the hdr saves physical addresses. */ - hdr->kernel_addr = VA(hdr->kernel_addr); - hdr->ramdisk_addr = VA(hdr->ramdisk_addr); - hdr->tags_addr = VA(hdr->tags_addr); - - /* 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)) - { - dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n"); - return; - } - -#if DEVICE_TREE - /* find correct dtb and copy it to right location */ - ret = copy_dtb(data); - - dtb_copied = !ret ? 1 : 0; -#else - if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE)) - { - dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n"); - return; - } -#endif - - /* Load ramdisk & kernel */ - memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size); - memmove((void*) hdr->kernel_addr, ptr + page_size, hdr->kernel_size); - -#if DEVICE_TREE - /* - * If dtb is not found look for appended DTB in the kernel. - * 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 - */ - if (!dtb_copied) { - void *dtb; - dtb = dev_tree_appended((void *)hdr->kernel_addr, hdr->kernel_size, - (void *)hdr->tags_addr); - if (!dtb) { - fastboot_fail("dtb not found"); - return; - } - } -#endif - -#ifndef DEVICE_TREE - if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE)) - { - dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n"); - return; - } -#endif - - fastboot_okay(""); - fastboot_stop(); - - boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr, - (const char*) hdr->cmdline, board_machtype(), - (void*) hdr->ramdisk_addr, hdr->ramdisk_size); -} - -void cmd_erase(const char *arg, void *data, unsigned sz) -{ - struct ptentry *ptn; - struct ptable *ptable; - - ptable = flash_get_ptable(); - if (ptable == NULL) { - fastboot_fail("partition table doesn't exist"); - return; - } - - ptn = ptable_find(ptable, arg); - if (ptn == NULL) { - fastboot_fail("unknown partition name"); - return; - } - - if (flash_erase(ptn)) { - fastboot_fail("failed to erase partition"); - return; - } - fastboot_okay(""); -} - - -void cmd_erase_mmc(const char *arg, void *data, unsigned sz) -{ - BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE); - unsigned long long ptn = 0; - unsigned long long size = 0; - int index = INVALID_PTN; - uint8_t lun = 0; - - index = partition_get_index(arg); - ptn = partition_get_offset(index); - size = partition_get_size(index); - - if(ptn == 0) { - fastboot_fail("Partition table doesn't exist\n"); - return; - } - - lun = partition_get_lun(index); - mmc_set_lun(lun); - -#if MMC_SDHCI_SUPPORT - if (mmc_erase_card(ptn, size)) { - fastboot_fail("failed to erase partition\n"); - return; - } -#else - size = partition_get_size(index); - if (size > DEFAULT_ERASE_SIZE) - size = DEFAULT_ERASE_SIZE; - - /* Simple inefficient version of erase. Just writing - 0 in first several blocks */ - if (mmc_write(ptn , size, (unsigned int *)out)) { - fastboot_fail("failed to erase partition"); - return; - } -#endif - fastboot_okay(""); -} - - -void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz) -{ - unsigned long long ptn = 0; - unsigned long long size = 0; - int index = INVALID_PTN; - char *token = NULL; - char *pname = NULL; - uint8_t lun = 0; - bool lun_set = false; - - token = strtok(arg, ":"); - pname = token; - token = strtok(NULL, ":"); - if(token) - { - lun = atoi(token); - mmc_set_lun(lun); - lun_set = true; - } - - if (pname) - { - if (!strcmp(pname, "partition")) - { - dprintf(INFO, "Attempt to write partition image.\n"); - if (write_partition(sz, (unsigned char *) data)) { - fastboot_fail("failed to write partition"); - return; - } - } - else - { - index = partition_get_index(pname); - ptn = partition_get_offset(index); - if(ptn == 0) { - fastboot_fail("partition table doesn't exist"); - return; - } - - if (!strcmp(pname, "boot") || !strcmp(pname, "recovery")) { - if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { - fastboot_fail("image is not a boot image"); - return; - } - } - - if(!lun_set) - { - lun = partition_get_lun(index); - mmc_set_lun(lun); - } - - size = partition_get_size(index); - if (ROUND_TO_PAGE(sz,511) > size) { - fastboot_fail("size too large"); - return; - } - else if (mmc_write(ptn , sz, (unsigned int *)data)) { - fastboot_fail("flash write failure"); - return; - } - } - } - fastboot_okay(""); - return; -} - void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz) { unsigned int chunk; @@ -2016,628 +203,3 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz) fastboot_okay(""); return; } - -void cmd_flash_mmc(const char *arg, void *data, unsigned sz) -{ - sparse_header_t *sparse_header; - /* 8 Byte Magic + 2048 Byte xml + Encrypted Data */ - unsigned int *magic_number = (unsigned int *) data; - -#ifdef SSD_ENABLE - int ret=0; - uint32 major_version=0; - uint32 minor_version=0; - - ret = scm_svc_version(&major_version,&minor_version); - if(!ret) - { - if(major_version >= 2) - { - if( !strcmp(arg, "ssd") || !strcmp(arg, "tqs") ) - { - ret = encrypt_scm((uint32 **) &data, &sz); - if (ret != 0) { - dprintf(CRITICAL, "ERROR: Encryption Failure\n"); - return; - } - - /* Protect only for SSD */ - if (!strcmp(arg, "ssd")) { - ret = scm_protect_keystore((uint32 *) data, sz); - if (ret != 0) { - dprintf(CRITICAL, "ERROR: scm_protect_keystore Failed\n"); - return; - } - } - } - else - { - ret = decrypt_scm_v2((uint32 **) &data, &sz); - if(ret != 0) - { - dprintf(CRITICAL,"ERROR: Decryption Failure\n"); - return; - } - } - } - else - { - if (magic_number[0] == DECRYPT_MAGIC_0 && - magic_number[1] == DECRYPT_MAGIC_1) - { - ret = decrypt_scm((uint32 **) &data, &sz); - if (ret != 0) { - dprintf(CRITICAL, "ERROR: Invalid secure image\n"); - return; - } - } - else if (magic_number[0] == ENCRYPT_MAGIC_0 && - magic_number[1] == ENCRYPT_MAGIC_1) - { - ret = encrypt_scm((uint32 **) &data, &sz); - if (ret != 0) { - dprintf(CRITICAL, "ERROR: Encryption Failure\n"); - return; - } - } - } - } - else - { - dprintf(CRITICAL,"INVALID SVC Version\n"); - return; - } -#endif /* SSD_ENABLE */ - - sparse_header = (sparse_header_t *) data; - if (sparse_header->magic != SPARSE_HEADER_MAGIC) - cmd_flash_mmc_img(arg, data, sz); - else - cmd_flash_mmc_sparse_img(arg, data, sz); - return; -} - -void cmd_flash(const char *arg, void *data, unsigned sz) -{ - struct ptentry *ptn; - struct ptable *ptable; - unsigned extra = 0; - - ptable = flash_get_ptable(); - if (ptable == NULL) { - fastboot_fail("partition table doesn't exist"); - return; - } - - ptn = ptable_find(ptable, arg); - if (ptn == NULL) { - fastboot_fail("unknown partition name"); - return; - } - - if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) { - if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { - fastboot_fail("image is not a boot image"); - return; - } - } - - if (!strcmp(ptn->name, "system") - || !strcmp(ptn->name, "userdata") - || !strcmp(ptn->name, "persist") - || !strcmp(ptn->name, "recoveryfs") - || !strcmp(ptn->name, "modem")) - { - if (memcmp((void *)data, UBI_MAGIC, UBI_MAGIC_SIZE)) - extra = 1; - else - extra = 0; - } - else - sz = ROUND_TO_PAGE(sz, page_mask); - - dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name); - if (flash_write(ptn, extra, data, sz)) { - fastboot_fail("flash write failure"); - return; - } - dprintf(INFO, "partition '%s' updated\n", ptn->name); - fastboot_okay(""); -} - -void cmd_continue(const char *arg, void *data, unsigned sz) -{ - fastboot_okay(""); - fastboot_stop(); - if (target_is_emmc_boot()) - { - boot_linux_from_mmc(); - } - else - { - boot_linux_from_flash(); - } -} - -void cmd_reboot(const char *arg, void *data, unsigned sz) -{ - dprintf(INFO, "rebooting the device\n"); - fastboot_okay(""); - reboot_device(0); -} - -void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz) -{ - dprintf(INFO, "rebooting the device\n"); - fastboot_okay(""); - reboot_device(FASTBOOT_MODE); -} - -void cmd_oem_enable_charger_screen(const char *arg, void *data, unsigned size) -{ - dprintf(INFO, "Enabling charger screen check\n"); - device.charger_screen_enabled = 1; - write_device_info(&device); - fastboot_okay(""); -} - -void cmd_oem_disable_charger_screen(const char *arg, void *data, unsigned size) -{ - dprintf(INFO, "Disabling charger screen check\n"); - device.charger_screen_enabled = 0; - write_device_info(&device); - fastboot_okay(""); -} - -void cmd_oem_select_display_panel(const char *arg, void *data, unsigned size) -{ - dprintf(INFO, "Selecting display panel %s\n", arg); - if (arg) - strlcpy(device.display_panel, arg, - sizeof(device.display_panel)); - write_device_info(&device); - fastboot_okay(""); -} - -void cmd_oem_unlock(const char *arg, void *data, unsigned sz) -{ - if(!device.is_unlocked) - { - device.is_unlocked = 1; - write_device_info(&device); - } - fastboot_okay(""); -} - -void cmd_oem_devinfo(const char *arg, void *data, unsigned sz) -{ - char response[128]; - snprintf(response, sizeof(response), "\tDevice tampered: %s", (device.is_tampered ? "true" : "false")); - fastboot_info(response); - snprintf(response, sizeof(response), "\tDevice unlocked: %s", (device.is_unlocked ? "true" : "false")); - fastboot_info(response); - snprintf(response, sizeof(response), "\tCharger screen enabled: %s", (device.charger_screen_enabled ? "true" : "false")); - fastboot_info(response); - snprintf(response, sizeof(response), "\tDisplay panel: %s", (device.display_panel)); - fastboot_info(response); - fastboot_okay(""); -} - -void cmd_preflash(const char *arg, void *data, unsigned sz) -{ - fastboot_okay(""); -} - -static struct fbimage logo_header = {0}; -struct fbimage* splash_screen_flash(); - -int splash_screen_check_header(struct fbimage *logo) -{ - if (memcmp(logo->header.magic, LOGO_IMG_MAGIC, 8)) - return -1; - if (logo->header.width == 0 || logo->header.height == 0) - return -1; - return 0; -} - -struct fbimage* splash_screen_flash() -{ - struct ptentry *ptn; - struct ptable *ptable; - struct fbcon_config *fb_display = NULL; - struct fbimage *logo = &logo_header; - - - ptable = flash_get_ptable(); - if (ptable == NULL) { - dprintf(CRITICAL, "ERROR: Partition table not found\n"); - return NULL; - } - ptn = ptable_find(ptable, "splash"); - if (ptn == NULL) { - dprintf(CRITICAL, "ERROR: splash Partition not found\n"); - return NULL; - } - - if (flash_read(ptn, 0,(unsigned int *) logo, sizeof(logo->header))) { - dprintf(CRITICAL, "ERROR: Cannot read boot image header\n"); - return NULL; - } - - if (splash_screen_check_header(logo)) { - dprintf(CRITICAL, "ERROR: Boot image header invalid\n"); - return NULL; - } - - fb_display = fbcon_display(); - if (fb_display) { - uint8_t *base = (uint8_t *) fb_display->base; - if (logo->header.width != fb_display->width || logo->header.height != fb_display->height) { - base += LOGO_IMG_OFFSET; - } - - if (flash_read(ptn + sizeof(logo->header), 0, - base, - ((((logo->header.width * logo->header.height * fb_display->bpp/8) + 511) >> 9) << 9))) { - fbcon_clear(); - dprintf(CRITICAL, "ERROR: Cannot read splash image\n"); - return NULL; - } - logo->image = base; - } - - return logo; -} - -struct fbimage* splash_screen_mmc() -{ - int index = INVALID_PTN; - unsigned long long ptn = 0; - struct fbcon_config *fb_display = NULL; - struct fbimage *logo = &logo_header; - - index = partition_get_index("splash"); - if (index == 0) { - dprintf(CRITICAL, "ERROR: splash Partition table not found\n"); - return NULL; - } - - ptn = partition_get_offset(index); - if (ptn == 0) { - dprintf(CRITICAL, "ERROR: splash Partition invalid\n"); - return NULL; - } - - if (mmc_read(ptn, (unsigned int *) logo, sizeof(logo->header))) { - dprintf(CRITICAL, "ERROR: Cannot read splash image header\n"); - return NULL; - } - - if (splash_screen_check_header(logo)) { - dprintf(CRITICAL, "ERROR: Splash image header invalid\n"); - return NULL; - } - - fb_display = fbcon_display(); - if (fb_display) { - uint8_t *base = (uint8_t *) fb_display->base; - if (logo->header.width != fb_display->width || logo->header.height != fb_display->height) - base += LOGO_IMG_OFFSET; - - if (mmc_read(ptn + sizeof(logo->header), - base, - ((((logo->header.width * logo->header.height * fb_display->bpp/8) + 511) >> 9) << 9))) { - fbcon_clear(); - dprintf(CRITICAL, "ERROR: Cannot read splash image\n"); - return NULL; - } - - logo->image = base; - } - - return logo; -} - - -struct fbimage* fetch_image_from_partition() -{ - if (target_is_emmc_boot()) { - return splash_screen_mmc(); - } else { - return splash_screen_flash(); - } -} - -/* Get the size from partiton name */ -static void get_partition_size(const char *arg, char *response) -{ - uint64_t ptn = 0; - uint64_t size; - int index = INVALID_PTN; - - index = partition_get_index(arg); - - if (index == INVALID_PTN) - { - dprintf(CRITICAL, "Invalid partition index\n"); - return; - } - - ptn = partition_get_offset(index); - - if(!ptn) - { - dprintf(CRITICAL, "Invalid partition name %s\n", arg); - return; - } - - size = partition_get_size(index); - - snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size); - return; -} - -/* - * Publish the partition type & size info - * fastboot getvar will publish the required information. - * fastboot getvar partition_size:<partition_name>: partition size in hex - * fastboot getvar partition_type:<partition_name>: partition type (ext/fat) - */ -static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts) -{ - uint8_t i; - - for (i = 0; i < num_parts; i++) { - get_partition_size(info[i].part_name, info[i].size_response); - - if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE) - { - dprintf(CRITICAL, "partition size name truncated\n"); - return; - } - if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE) - { - dprintf(CRITICAL, "partition type name truncated\n"); - return; - } - - /* publish partition size & type info */ - fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response); - fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response); - } -} - -/* register commands and variables for fastboot */ -void aboot_fastboot_register_commands(void) -{ - if (target_is_emmc_boot()) - { - fastboot_register("flash:", cmd_flash_mmc); - fastboot_register("erase:", cmd_erase_mmc); - } - else - { - fastboot_register("flash:", cmd_flash); - fastboot_register("erase:", cmd_erase); - } - - fastboot_register("boot", cmd_boot); - fastboot_register("continue", cmd_continue); - fastboot_register("reboot", cmd_reboot); - fastboot_register("reboot-bootloader", cmd_reboot_bootloader); - fastboot_register("oem unlock", cmd_oem_unlock); - fastboot_register("oem device-info", cmd_oem_devinfo); - fastboot_register("preflash", cmd_preflash); - fastboot_register("oem enable-charger-screen", - cmd_oem_enable_charger_screen); - fastboot_register("oem disable-charger-screen", - cmd_oem_disable_charger_screen); - fastboot_register("oem select-display-panel", - cmd_oem_select_display_panel); - /* publish variables and their values */ - fastboot_publish("product", TARGET(BOARD)); - fastboot_publish("kernel", "lk"); - fastboot_publish("serialno", sn_buf); - - /* - * partition info is supported only for emmc partitions - * Calling this for NAND prints some error messages which - * is harmless but misleading. Avoid calling this for NAND - * devices. - */ - if (target_is_emmc_boot()) - publish_getvar_partition_info(part_info, ARRAY_SIZE(part_info)); - - /* Max download size supported */ - snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x", - target_get_max_flash_size()); - fastboot_publish("max-download-size", (const char *) max_download_size); - /* Is the charger screen check enabled */ - snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d", - device.charger_screen_enabled); - fastboot_publish("charger-screen-enabled", - (const char *) charger_screen_enabled); - snprintf(panel_display_mode, MAX_RSP_SIZE, "%s", - device.display_panel); - fastboot_publish("display-panel", - (const char *) panel_display_mode); -} - -void aboot_init(const struct app_descriptor *app) -{ - unsigned reboot_mode = 0; - bool boot_into_fastboot = false; - - /* Setup page size information for nv storage */ - if (target_is_emmc_boot()) - { - page_size = mmc_page_size(); - page_mask = page_size - 1; - } - else - { - page_size = flash_page_size(); - page_mask = page_size - 1; - } - - ASSERT((MEMBASE + MEMSIZE) > MEMBASE); - - read_device_info(&device); - - /* Display splash screen if enabled */ -#if DISPLAY_SPLASH_SCREEN - dprintf(SPEW, "Display Init: Start\n"); - target_display_init(device.display_panel); - dprintf(SPEW, "Display Init: Done\n"); -#endif - - - target_serialno((unsigned char *) sn_buf); - dprintf(SPEW,"serial number: %s\n",sn_buf); - - memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE); - - /* Check if we should do something other than booting up */ - if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN)) - { - dprintf(ALWAYS,"dload mode key sequence detected\n"); - if (set_download_mode(EMERGENCY_DLOAD)) - { - dprintf(CRITICAL,"dload mode not supported by target\n"); - } - else - { - reboot_device(DLOAD); - dprintf(CRITICAL,"Failed to reboot into dload mode\n"); - } - boot_into_fastboot = true; - } - if (!boot_into_fastboot) - { - if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP)) - boot_into_recovery = 1; - if (!boot_into_recovery && - (keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN))) - boot_into_fastboot = true; - } - #if NO_KEYPAD_DRIVER - if (fastboot_trigger()) - boot_into_fastboot = true; - #endif - - reboot_mode = check_reboot_mode(); - if (reboot_mode == RECOVERY_MODE) { - boot_into_recovery = 1; - } else if(reboot_mode == FASTBOOT_MODE) { - boot_into_fastboot = true; - } - - if (!boot_into_fastboot) - { - if (target_is_emmc_boot()) - { - if(emmc_recovery_init()) - dprintf(ALWAYS,"error in emmc_recovery_init\n"); - if(target_use_signed_kernel()) - { - if((device.is_unlocked) || (device.is_tampered)) - { - #ifdef TZ_TAMPER_FUSE - set_tamper_fuse_cmd(); - #endif - #if USE_PCOM_SECBOOT - set_tamper_flag(device.is_tampered); - #endif - } - } - boot_linux_from_mmc(); - } - else - { - recovery_init(); - #if USE_PCOM_SECBOOT - if((device.is_unlocked) || (device.is_tampered)) - set_tamper_flag(device.is_tampered); - #endif - boot_linux_from_flash(); - } - dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting " - "to fastboot mode.\n"); - } - - /* We are here means regular boot did not happen. Start fastboot. */ - - /* register aboot specific fastboot commands */ - aboot_fastboot_register_commands(); - - /* dump partition table for debug info */ - partition_dump(); - - /* initialize and start fastboot */ - fastboot_init(target_get_scratch_address(), target_get_max_flash_size()); -} - -uint32_t get_page_size() -{ - return page_size; -} - -/* - * Calculated and save hash (SHA256) for non-signed boot image. - * - * Hash the same data that is checked on the signed boot image. - * Kernel and Ramdisk are already read to memory buffers. - * Need to read the entire device-tree from mmc - * since non-signed image only read the DT tags of the relevant platform. - * - * @param kernel_addr - kernel bufer - * @param kernel_actual - kernel size in bytes - * @param ramdisk_addr - ramdisk buffer - * @param ramdisk_actual - ramdisk size - * @param ptn - partition - * @param dt_offset - device tree offset on mmc partition - * @param dt_size - * - * @return int - 0 on success, negative value on failure. - */ -int aboot_save_boot_hash_mmc(void *kernel_addr, unsigned kernel_actual, - void *ramdisk_addr, unsigned ramdisk_actual, - unsigned long long ptn, - unsigned dt_offset, unsigned dt_size) -{ - SHA256_CTX sha256_ctx; - char digest[32]={0}; - char *buf = (char *)target_get_scratch_address(); - unsigned dt_actual = ROUND_TO_PAGE(dt_size, page_mask); - unsigned imagesize_actual = page_size + kernel_actual + ramdisk_actual + dt_actual; - - SHA256_Init(&sha256_ctx); - - /* Read Boot Header */ - if (mmc_read(ptn, buf, page_size)) - { - dprintf(CRITICAL, "ERROR: mmc_read() fail.\n"); - return -1; - } - /* Read entire Device Tree */ - if (mmc_read(ptn + dt_offset, buf+page_size, dt_actual)) - { - dprintf(CRITICAL, "ERROR: mmc_read() fail.\n"); - return -1; - } - SHA256_Update(&sha256_ctx, buf, page_size); // Boot Header - SHA256_Update(&sha256_ctx, kernel_addr, kernel_actual); - SHA256_Update(&sha256_ctx, ramdisk_addr, ramdisk_actual); - SHA256_Update(&sha256_ctx, buf+page_size, dt_actual); // Device Tree - - SHA256_Final(digest, &sha256_ctx); - - save_kernel_hash_cmd(digest); - dprintf(INFO, "aboot_save_boot_hash_mmc: imagesize_actual size %d bytes.\n", (int) imagesize_actual); - - return 0; -} - -APP_START(aboot) - .init = aboot_init, -APP_END |