static uint32_t mmc_zero_out(struct mmc_device* dev, uint32_t blk_addr, uint32_t num_blks) { uint32_t *out; uint32_t block_size = mmc_get_device_blocksize(); uint32_t erase_size = (block_size * num_blks); uint32_t scratch_size = target_get_max_flash_size(); dprintf(INFO, "erasing 0x%x:0x%x\n", blk_addr, num_blks); if (erase_size <= scratch_size) { /* Use scratch address if the unaligned blocks */ out = (uint32_t *) target_get_scratch_address(); } else { dprintf(CRITICAL, "Erase Fail: Erase size: %u is bigger than scratch region\n", scratch_size); return 1; } memset((void *)out, 0, erase_size); /* Flush the data to memory before writing to storage */ arch_clean_invalidate_cache_range((addr_t) out , erase_size); if (mmc_sdhci_write(dev, out, blk_addr, num_blks)) { dprintf(CRITICAL, "failed to erase the partition: %x\n", blk_addr); return 1; } return 0; }
int update_firmware_image (struct update_header *header, char *name) { struct ptentry *ptn; struct ptable *ptable; unsigned offset = 0; unsigned pagesize = flash_page_size(); unsigned pagemask = pagesize -1; unsigned n = 0; void *scratch_addr = target_get_scratch_address(); ptable = flash_get_ptable(); if (ptable == NULL) { dprintf(CRITICAL, "ERROR: Partition table not found\n"); return -1; } ptn = ptable_find(ptable, "cache"); if (ptn == NULL) { dprintf(CRITICAL, "ERROR: No cache partition found\n"); return -1; } offset += header->image_offset; n = (header->image_length + pagemask) & (~pagemask); if (flash_read(ptn, offset, scratch_addr, n)) { dprintf(CRITICAL, "ERROR: Cannot read radio image\n"); return -1; } ptn = ptable_find(ptable, name); if (ptn == NULL) { dprintf(CRITICAL, "ERROR: No %s partition found\n", name); return -1; } if (flash_write(ptn, 0, scratch_addr, n)) { dprintf(CRITICAL, "ERROR: flash write fail!\n"); return -1; } dprintf(INFO, "Partition writen successfully!"); return 0; }
int set_recovery_message(const struct recovery_message *in) { struct ptentry *ptn; struct ptable *ptable; unsigned offset = 0; unsigned pagesize = flash_page_size(); unsigned n = 0; void *scratch_addr = target_get_scratch_address(); ptable = flash_get_ptable(); if (ptable == NULL) { dprintf(CRITICAL, "ERROR: Partition table not found\n"); return -1; } ptn = ptable_find(ptable, "misc"); if (ptn == NULL) { dprintf(CRITICAL, "ERROR: No misc partition found\n"); return -1; } n = pagesize * (MISC_COMMAND_PAGE + 1); if (flash_read(ptn, offset, scratch_addr, n)) { dprintf(CRITICAL, "ERROR: Cannot read recovery_header\n"); return -1; } offset += (pagesize * MISC_COMMAND_PAGE); offset += (unsigned) scratch_addr; memcpy((void *) offset, in, sizeof(*in)); if (flash_write(ptn, 0, scratch_addr, n)) { dprintf(CRITICAL, "ERROR: flash write fail!\n"); return -1; } return 0; }
void cmd_boot(const char *arg, void *data, unsigned sz) { unsigned kernel_actual; unsigned ramdisk_actual; static struct boot_img_hdr hdr; char *ptr = ((char*) data); unsigned page_size = 0; unsigned page_mask = 0; int strlen = 0; if (sz < sizeof(hdr)) { fastboot_fail("invalid bootimage header"); return; } memcpy(&hdr, data, sizeof(hdr)); printf("\n============================================================\n"); hdr.magic[7] = '\0'; printf("[%s] Android Boot IMG Hdr - Magic : %s\n",MODULE_NAME,hdr.magic); printf("[%s] Android Boot IMG Hdr - Kernel Size : 0x%x\n",MODULE_NAME,hdr.kernel_size); printf("[%s] Android Boot IMG Hdr - Rootfs Size : 0x%x\n",MODULE_NAME,hdr.ramdisk_size); printf("[%s] Android Boot IMG Hdr - Page Size : 0x%x\n",MODULE_NAME,hdr.page_size); printf("============================================================\n"); /* ensure commandline is terminated */ hdr.cmdline[BOOT_ARGS_SIZE-1] = 0; if(hdr.page_size) { page_size = hdr.page_size; page_mask = page_size - 1; //page_mask = 2*1024 ; /*FIXME*/ } else { printf("[FASTBOOT] Please specify the storage page-size in the boot header!\n"); fastboot_fail("Please specify the storage page-size in the boot header!\n"); return; } kernel_actual = ROUND_TO_PAGE(hdr.kernel_size, page_mask); ramdisk_actual = ROUND_TO_PAGE(hdr.ramdisk_size, page_mask); /* sz should have atleast raw boot image */ if (page_size + kernel_actual + ramdisk_actual > sz) { fastboot_fail("incomplete bootimage"); return; } memmove((void*) hdr.kernel_addr, (ptr + MKIMG_HEADER_SZ + BIMG_HEADER_SZ), hdr.kernel_size); memmove((void*) hdr.ramdisk_addr, (ptr + MKIMG_HEADER_SZ + BIMG_HEADER_SZ + kernel_actual), hdr.ramdisk_size); strlen += sprintf((const char*) hdr.cmdline, "%s lcm=%1d-%s", hdr.cmdline, DISP_IsLcmFound(), mt_disp_get_lcm_id()); strlen += sprintf((const char*) hdr.cmdline, "%s fps=%1d", hdr.cmdline, mt_disp_get_lcd_time()); fastboot_okay(""); udc_stop(); mtk_wdt_init(); //re-open wdt g_boot_mode = NORMAL_BOOT; boot_linux((void*) hdr.kernel_addr, (void*) hdr.tags_addr, (const char*) hdr.cmdline, board_machtype(), (void*) hdr.ramdisk_addr, hdr.ramdisk_size); #if 0 unsigned kernel_actual; unsigned ramdisk_actual; struct boot_img_hdr boot_hdr; unsigned int k_pg_cnt = 0; unsigned int r_pg_cnt = 0; unsigned int b_pg_cnt = 0; unsigned int size_b = 0; unsigned int pg_sz = 2*1024 ; int strlen = 0; /*copy hdr data from download_base*/ memcpy(&boot_hdr, data, sizeof(boot_hdr)); /* ensure commandline is terminated */ boot_hdr.cmdline[BOOT_ARGS_SIZE-1] = 0; printf("\n============================================================\n"); boot_hdr.magic[7] = '\0'; printf("[%s] Android Boot IMG Hdr - Magic : %s\n",MODULE_NAME,boot_hdr.magic); printf("[%s] Android Boot IMG Hdr - Kernel Size : 0x%x\n",MODULE_NAME,boot_hdr.kernel_size); printf("[%s] Android Boot IMG Hdr - Rootfs Size : 0x%x\n",MODULE_NAME,boot_hdr.ramdisk_size); printf("[%s] Android Boot IMG Hdr - Page Size : 0x%x\n",MODULE_NAME,boot_hdr.page_size); printf("============================================================\n"); //*************** //* check partition magic //* if (strncmp(boot_hdr.magic,BOOT_MAGIC, sizeof(BOOT_MAGIC))!=0) { printf("[%s] boot image header magic error\n", MODULE_NAME); return -1; } g_kmem_off = (unsigned int)target_get_scratch_address(); g_kmem_off = g_kmem_off + MKIMG_HEADER_SZ + BIMG_HEADER_SZ; if(boot_hdr.kernel_size % pg_sz == 0) { k_pg_cnt = boot_hdr.kernel_size / pg_sz; } else { k_pg_cnt = (boot_hdr.kernel_size / pg_sz) + 1; } if(boot_hdr.ramdisk_size % pg_sz == 0) { r_pg_cnt = boot_hdr.ramdisk_size / pg_sz; } else { r_pg_cnt = (boot_hdr.ramdisk_size / pg_sz) + 1; } printf(" > page count of kernel image = %d\n",k_pg_cnt); g_rmem_off = g_kmem_off + k_pg_cnt * pg_sz; printf(" > kernel mem offset = 0x%x\n",g_kmem_off); printf(" > rootfs mem offset = 0x%x\n",g_rmem_off); //*************** //* specify boot image size //* g_bimg_sz = (k_pg_cnt + r_pg_cnt + 2)* pg_sz; printf(" > boot image size = 0x%x\n",g_bimg_sz); memmove((void*)CFG_BOOTIMG_LOAD_ADDR , g_kmem_off, boot_hdr.kernel_size); memmove((void*)CFG_RAMDISK_LOAD_ADDR , g_rmem_off, boot_hdr.ramdisk_size); //custom_port_in_kernel(g_boot_mode, commanline); //strlen += sprintf(commanline, "%s lcm=%1d-%s", commanline, DISP_IsLcmFound(), mt_disp_get_lcm_id()); //strlen += sprintf(commanline, "%s fps=%1d", commanline, mt_disp_get_lcd_time()); fastboot_okay(""); udc_stop(); mtk_wdt_init(); boot_linux((void *)CFG_BOOTIMG_LOAD_ADDR, (unsigned *)CFG_BOOTARGS_ADDR, (const char*) boot_hdr.cmdline, board_machtype(), (void *)CFG_RAMDISK_LOAD_ADDR, boot_hdr.ramdisk_size); #endif }
int write_misc(unsigned page_offset, void *buf, unsigned size) { const char *ptn_name = "misc"; void *scratch_addr = target_get_scratch_address(); unsigned offset; unsigned aligned_size; if (size == 0 || buf == NULL || scratch_addr == NULL) return -1; if (target_is_emmc_boot()) { int index; unsigned long long ptn; unsigned long long ptn_size; index = partition_get_index(ptn_name); if (index == INVALID_PTN) { dprintf(CRITICAL, "No '%s' partition found\n", ptn_name); return -1; } ptn = partition_get_offset(index); ptn_size = partition_get_size(index); offset = page_offset * BLOCK_SIZE; aligned_size = ROUND_TO_PAGE(size, (unsigned)BLOCK_SIZE - 1); if (ptn_size < offset + aligned_size) { dprintf(CRITICAL, "Write request out of '%s' boundaries\n", ptn_name); return -1; } if (scratch_addr != buf) memcpy(scratch_addr, buf, size); if (mmc_write(ptn + offset, aligned_size, (unsigned int *)scratch_addr)) { dprintf(CRITICAL, "Writing MMC failed\n"); return -1; } } else { struct ptentry *ptn; struct ptable *ptable; unsigned pagesize = flash_page_size(); ptable = flash_get_ptable(); if (ptable == NULL) { dprintf(CRITICAL, "Partition table not found\n"); return -1; } ptn = ptable_find(ptable, ptn_name); if (ptn == NULL) { dprintf(CRITICAL, "No '%s' partition found\n", ptn_name); return -1; } offset = page_offset * pagesize; aligned_size = ROUND_TO_PAGE(size, pagesize - 1); if (ptn->length < offset + aligned_size) { dprintf(CRITICAL, "Write request out of '%s' boundaries\n", ptn_name); return -1; } if (scratch_addr != buf) memcpy(scratch_addr, buf, size); if (flash_write(ptn, offset, scratch_addr, aligned_size)) { dprintf(CRITICAL, "Writing flash failed\n"); return -1; } } return 0; }
} if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { jtag_fail("image is not a boot image"); return; } } if (!strcmp(ptn->name, "system") || !strcmp(ptn->name, "userdata") || !strcmp(ptn->name, "persist")) extra = ((page_size >> 9) * 16); else sz = ROUND_TO_PAGE(sz, page_mask); data = (void *)target_get_scratch_address(); dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name); if (flash_write(ptn, extra, data, sz)) { jtag_fail("flash write failure"); return; } dprintf(INFO, "partition '%s' updated\n", ptn->name); jtag_okay("Done"); enter_critical_section(); platform_uninit_timer(); arch_disable_cache(UCACHE); arch_disable_mmu(); } static unsigned char *tmpbuf = 0;