static int grub_load_from_tar(void) { // prepare block api priv.index = partition_get_index("aboot"); priv.ptn = partition_get_offset(priv.index) + 1024*1024; // 1MB offset to aboot priv.is_ramdisk = 0; tio.blksz = BLOCK_SIZE; tio.lba = partition_get_size(priv.index) / tio.blksz - 1; // search file if(tar_get_fileinfo(&tio, "./boot/grub/core.img", &fi)) { dprintf(CRITICAL, "%s: couldn't find core.img!\n", __func__); return -1; } // load file into RAM if(tar_read_file(&tio, &fi, (void*)GRUB_LOADING_ADDRESS_VIRT)) { dprintf(CRITICAL, "%s: couldn't read core.img!\n", __func__); return -1; } grub_bootdev = strdup("hd1"); grub_bootpath = strdup("/boot/grub"); grub_found_tar = 1; dprintf(INFO, "Loaded GRUB from TAR\n"); return 0; }
static int emmc_get_recovery_msg(struct recovery_message *in) { char *ptn_name = "misc"; unsigned long long ptn = 0; unsigned int size; int index = INVALID_PTN; size = mmc_get_device_blocksize(); index = partition_get_index((const char *) ptn_name); if (index < 0) { dprintf(CRITICAL, "%s: Partition not found\n", ptn_name); return -1; } ptn = partition_get_offset(index); mmc_set_lun(partition_get_lun(index)); if(ptn == 0) { dprintf(CRITICAL,"partition %s doesn't exist\n",ptn_name); return -1; } if (mmc_read(ptn , (unsigned int*)in, size)) { dprintf(CRITICAL,"mmc read failure %s %d\n",ptn_name, size); return -1; } return 0; }
static void ssd_load_keystore_from_emmc() { uint64_t ptn = 0; int index = -1; uint32_t size = SSD_PARTITION_SIZE; int ret = -1; uint32_t *buffer = (uint32_t *)memalign(CACHE_LINE, ROUNDUP(SSD_PARTITION_SIZE, CACHE_LINE)); if (!buffer) { dprintf(CRITICAL, "Error Allocating memory for SSD buffer\n"); ASSERT(0); } index = partition_get_index("ssd"); ptn = partition_get_offset(index); if(ptn == 0) { dprintf(CRITICAL,"ERROR: ssd parition not found"); return; } if(mmc_read(ptn, buffer, size)) { dprintf(CRITICAL,"ERROR:Cannot read data\n"); return; } ret = scm_protect_keystore((uint32_t *)&buffer[0],size); if(ret != 0) dprintf(CRITICAL,"ERROR: scm_protect_keystore Failed"); free(buffer); }
/** * Load images from EMMC */ static struct mdtp_fbimage* mdtp_read_mmc_image(uint32_t offset, uint32_t width, uint32_t height) { int index = INVALID_PTN; unsigned long long ptn = 0; struct mdtp_fbimage *logo = &g_mdtp_header; uint32_t block_size = mmc_get_device_blocksize(); index = partition_get_index("mdtp"); if (index == 0) { dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n"); return NULL; } ptn = partition_get_offset(index); if (ptn == 0) { dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n"); return NULL; } if (fb_config) { uint8_t *base = logo->image; unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE); if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*bytes_per_bpp, block_size))) { fbcon_clear(); dprintf(CRITICAL, "ERROR: mdtp image read failed\n"); return NULL; } logo->width = width; logo->height = height; } return logo; }
static int mdss_dsi_dfps_store_pll_codes(struct msm_panel_info *pinfo) { int ret = NO_ERROR; int index; unsigned long long ptn; index = partition_get_index("splash"); if (index == INVALID_PTN) { dprintf(INFO, "%s: splash partition table not found\n", __func__); ret = NO_ERROR; goto store_err; } ptn = partition_get_offset(index); if (ptn == 0) { dprintf(CRITICAL, "ERROR: splash Partition invalid offset\n"); ret = ERROR; goto store_err; } mmc_set_lun(partition_get_lun(index)); ret = mmc_write(ptn, sizeof(uint32_t), &pinfo->dfps); if (ret) dprintf(CRITICAL, "mmc write failed!\n"); store_err: return ret; }
void cmd_erase_emmc(const char *arg, void *data, unsigned sz) { #ifdef MTK_NEW_COMBO_EMMC_SUPPORT unsigned int part_id; #endif unsigned long long ptn = 0; unsigned long long size = 0; int index = INVALID_PTN; int erase_ret = MMC_ERR_NONE; char msg[256]; init_display_xy(); dprintf (DBG_LV, "Enter cmd_erase()\n"); index = partition_get_index(arg); #ifdef MTK_NEW_COMBO_EMMC_SUPPORT part_id = partition_get_region(index); #endif ptn = partition_get_offset(index); if(index == -1) { fastboot_fail_wrapper("Partition table doesn't exist"); return; } if(!is_support_erase(index)){ sprintf(msg,"partition '%s' not support erase\n",arg); fastboot_fail_wrapper(msg); return; } TIME_START; size = partition_get_size(index); #ifdef MTK_NEW_COMBO_EMMC_SUPPORT erase_ret = emmc_erase(part_id, ptn, partition_get_size(index)); #else erase_ret = emmc_erase(ptn, partition_get_size(index)); #endif if(erase_ret == MMC_ERR_NONE) { dprintf (DBG_LV, "emmc_erase() OK\n"); fastboot_ok_wrapper("Erase EMMC", size); } else { dprintf (DBG_LV, "emmc_erase() Fail\n"); snprintf(msg, sizeof(msg), "Erase error. code:%d", erase_ret); fastboot_fail_wrapper(msg); } return; }
static int read_misc(unsigned page_offset, void *buf, unsigned size) { const char *ptn_name = "misc"; uint32_t pagesize = get_page_size(); unsigned offset; if (size == 0 || buf == NULL) return -1; offset = page_offset * pagesize; 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); mmc_set_lun(partition_get_lun(index)); if (ptn_size < offset + size) { dprintf(CRITICAL, "Read request out of '%s' boundaries\n", ptn_name); return -1; } if (mmc_read(ptn + offset, (unsigned int *)buf, size)) { dprintf(CRITICAL, "Reading MMC failed\n"); return -1; } } else { dprintf(CRITICAL, "Misc partition not supported for NAND targets.\n"); return -1; } return 0; }
static int fastboot_data_part_wipe() { int ret = B_OK; int err; int index; #ifdef MTK_NEW_COMBO_EMMC_SUPPORT unsigned int part_id; #endif unsigned long long ptn; unsigned long long size; index = partition_get_index("userdata"); if (index == -1 || !is_support_erase(index)) { ret = PART_GET_INDEX_FAIL; return ret; } #ifdef MTK_NEW_COMBO_EMMC_SUPPORT part_id = partition_get_region(index); #endif ptn = partition_get_offset(index); size = partition_get_size(index); set_env("unlock_erase", "start"); #ifdef MTK_EMMC_SUPPORT #ifdef MTK_NEW_COMBO_EMMC_SUPPORT err = emmc_erase(part_id, ptn, size); #else err = emmc_erase(ptn, size); #endif #else err = nand_erase(ptn,(u64)size); #endif if (err) { ret = PART_ERASE_FAIL; set_env("unlock_erase", "fail"); } else { ret = B_OK; set_env("unlock_erase", "pass"); } return ret; }
static int read_user_keystore_ptn() { int index = INVALID_PTN; unsigned long long ptn = 0; index = partition_get_index(KEYSTORE_PTN_NAME); ptn = partition_get_offset(index); if(ptn == 0) { dprintf(CRITICAL, "boot_verifier: No keystore partition found\n"); return -1; } if (mmc_read(ptn, (unsigned int *) keystore_buf, mmc_page_size())) { dprintf(CRITICAL, "boot_verifier: Cannot read user keystore\n"); return -1; } return 0; }
void cmd_erase_nand(const char *arg, void *data, unsigned sz) { int index; u64 offset,size; char msg[256]; index = partition_get_index(arg); if(index == -1){ fastboot_fail_wrapper("partition get index fail"); return; } if(!is_support_erase(index)){ sprintf(msg,"partition '%s' not support erase\n",arg); fastboot_fail_wrapper(msg); return; } offset = partition_get_offset(index); if(offset == (u64)(-1)){ fastboot_fail_wrapper("partition get offset fail"); return; }else{ printf("get offset: 0x%llx\n",offset); } size = partition_get_size(index); if(size == (u64)(-1)){ fastboot_fail_wrapper("partition get size fail"); return; }else{ printf("get size: 0x%llx\n",size); } TIME_START; display_info("erase flash ...."); if(nand_erase(offset,size)!=0){ fastboot_fail_wrapper("failed to erase partition"); return; } fastboot_ok_wrapper("erase flash sucess",sz); return; }
static int mmcdev_open(struct ext4_blockdev *bdev) { struct private_mmc_data* mmcdata = mmcdev_get_privatedata(bdev); unsigned long long index = INVALID_PTN; unsigned long long size; // get partition ptn index = partition_get_index(mmcdata->partname); mmcdata->ptn = partition_get_offset(index); if(mmcdata->ptn == 0) return EIO; // get size size = partition_get_size(index); bdev->ph_bsize = mmc_get_device_blocksize(); bdev->ph_bcnt = size / bdev->ph_bsize; bdev->ph_bbuf = (uint8_t*)malloc(sizeof(uint8_t)*bdev->ph_bsize); return EOK; }
static int get_fota_cookie_mmc(void) { unsigned long long ptn = 0; int index = -1; unsigned int cookie = 0; index = partition_get_index("FOTA"); ptn = partition_get_offset(index); if(ptn == 0) { dprintf(CRITICAL,"ERROR: FOTA partition not found\n"); return 0; } if(read_from_mmc(ptn, sizeof(unsigned int), &cookie)) { dprintf(CRITICAL, "ERROR: Cannot read cookie info\n"); return 0; } return cookie; }
void target_load_ssd_keystore(void) { uint64_t ptn; int index; uint64_t size; uint32_t *buffer; if (!target_is_ssd_enabled()) return; index = partition_get_index("ssd"); ptn = partition_get_offset(index); if (ptn == 0){ dprintf(CRITICAL, "Error: ssd partition not found\n"); return; } size = partition_get_size(index); if (size == 0) { dprintf(CRITICAL, "Error: invalid ssd partition size\n"); return; } buffer = memalign(CACHE_LINE, ROUNDUP(size, CACHE_LINE)); if (!buffer) { dprintf(CRITICAL, "Error: allocating memory for ssd buffer\n"); return; } if (mmc_read(ptn, buffer, size)) { dprintf(CRITICAL, "Error: cannot read data\n"); free(buffer); return; } clock_ce_enable(SSD_CE_INSTANCE); scm_protect_keystore(buffer, size); clock_ce_disable(SSD_CE_INSTANCE); free(buffer); }
int LGE_set_bootloader_message(const struct gota_stage_message *out) { char *ptn_name = "misc"; unsigned long long ptn = 0; unsigned int size = ROUND_TO_PAGE(sizeof(*out),511); unsigned char data[size]; int index = INVALID_PTN; index = partition_get_index((const char *) ptn_name); ptn = partition_get_offset(index); if(ptn == 0) { dprintf(CRITICAL,"partition %s doesn't exist\n",ptn_name); return -1; } memcpy(data, out, sizeof(*out)); if (mmc_write(ptn , size, (unsigned int*)data)) { dprintf(CRITICAL,"mmc write failure %s %d\n",ptn_name, sizeof(*out)); return -1; } return 0; }
static int emmc_get_recovery_msg(struct recovery_message *in) { char *ptn_name = "misc"; unsigned long long ptn = 0; unsigned int size = ROUND_TO_PAGE(sizeof(*in),511); unsigned char data[size]; int index = INVALID_PTN; index = partition_get_index((unsigned char *) ptn_name); ptn = partition_get_offset(index); if(ptn == 0) { dprintf(CRITICAL,"partition %s doesn't exist\n",ptn_name); return -1; } if (mmc_read(ptn , (unsigned int*)data, size)) { dprintf(CRITICAL,"mmc read failure %s %d\n",ptn_name, size); return -1; } memcpy(in, data, sizeof(*in)); return 0; }
void cmd_flash_nand(const char *arg, void *data, unsigned sz) { int index; u64 offset,size; bool partition_type; char *p_type; char msg[256]; if(sz == 0) { fastboot_okay(""); return; } index = partition_get_index(arg); if(index == -1){ fastboot_fail_wrapper("partition get index fail"); return; } if(!is_support_flash(index)){ sprintf(msg,"partition '%s' not support flash\n",arg); fastboot_fail_wrapper(msg); return; } offset = partition_get_offset(index); if(offset == -1){ fastboot_fail_wrapper("partition get offset fail"); return; }else{ printf("get offset: 0x%llx\n",offset); } size = partition_get_size(index); if(size == -1){ fastboot_fail_wrapper("partition get size fail"); return; }else{ printf("get size: 0x%llx\n",size); } if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC))) { fastboot_fail_wrapper("image is not a boot image"); return; } } partition_get_type(index,&p_type); partition_type = (!strcmp(p_type,"yaffs2"))?1:0; TIME_START; display_info("write flash ...."); printf("writing %d bytes to '%s' '%s' partition_type %d\n", sz, arg,p_type,partition_type); if (nand_write_img((u32)offset, data, sz,(u32)size,partition_type)) { fastboot_fail_wrapper("nand write image failure"); return; } printf("partition '%s' updated\n", arg); fastboot_ok_wrapper("write flash sucess",sz); return; }
BOOL write_to_nand(u8* data, u32 length) { u64 paritition_size = 0; int next_flip = 0; u32 index; BOOL partition_type; s8* p_type; //u32 pre_chksum = 0; //u32 post_chksum = 0; int r; if(sto_info.first_run) { r = get_partition_name(data, length, sto_info.partition_name); if(r < 0) { display_info("ASSERT!! get_partition_name() Fail"); return FALSE; } index = partition_get_index(sto_info.partition_name); // if(index == -1) { display_info("ASSERT!! Brick phone??"); return FALSE; } if(!is_support_flash(index)) { display_info("ASSERT!! Dont support system??"); return FALSE; } //verify boot partition. if (!strcmp(sto_info.partition_name, "boot") || !strcmp(sto_info.partition_name, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC))) { display_info("image is not a boot image"); return FALSE; } } paritition_size = partition_get_size(index); dprintf(DBG_LV, "[index:%d]-[partitionSize:%lld]-[downSize:%d]\n", index, paritition_size, sto_info.to_write_data_len); if (ROUND_TO_PAGE(sto_info.to_write_data_len,511) > paritition_size) { display_info("size too large, space small."); dprintf(DBG_LV, "size too large, space small."); return FALSE; } partition_get_type(index,&p_type); partition_type = (!strcmp(p_type,"yaffs2")) ? TRUE : FALSE; sto_info.image_base_addr = partition_get_offset(index); //NAND has no sparse image. //sto_info.unsparse_status.image_base_addr = sto_info.image_base_addr; //sto_info.is_sparse_image = is_sparse_image(data, length); sto_info.first_run = 0; } if (0 != nand_write_img((u32)(sto_info.image_base_addr+sto_info.bulk_image_offset), (void*)data, length,(u32)paritition_size, partition_type)) { dprintf(DBG_LV, "nand_write_img() Failed.\n"); display_info("Error in write bulk in NAND."); return FALSE; } if(sto_info.checksum_enabled) { //NAND do not support read() now. } sto_info.bulk_image_offset += length; return TRUE; }
static int mdss_dsi_dfps_get_stored_pll_codes(struct msm_panel_info *pinfo) { int ret = NO_ERROR; int index; unsigned long long ptn; uint32_t blocksize; struct dfps_info *dfps; index = partition_get_index("splash"); if (index == INVALID_PTN) { dprintf(INFO, "%s: splash partition table not found\n", __func__); ret = NO_ERROR; goto splash_err; } ptn = partition_get_offset(index); if (ptn == 0) { dprintf(CRITICAL, "ERROR: splash Partition invalid offset\n"); ret = ERROR; goto splash_err; } mmc_set_lun(partition_get_lun(index)); blocksize = mmc_get_device_blocksize(); if (blocksize == 0) { dprintf(CRITICAL, "ERROR:splash Partition invalid blocksize\n"); ret = ERROR; goto splash_err; } dfps = (struct dfps_info *)memalign(CACHE_LINE, ROUNDUP(PAGE_SIZE, CACHE_LINE)); if (!dfps) { dprintf(CRITICAL, "ERROR:splash Partition invalid memory\n"); ret = ERROR; goto splash_err; } if (mmc_read(ptn, (uint32_t *) dfps, blocksize)) { dprintf(CRITICAL, "mmc read splash failure%d\n", PAGE_SIZE); ret = ERROR; free(dfps); goto splash_err; } dprintf(SPEW, "enable=%d cnt=%d\n", dfps->panel_dfps.enabled, dfps->panel_dfps.frame_rate_cnt); if (!dfps->panel_dfps.enabled || dfps->panel_dfps.frame_rate_cnt > DFPS_MAX_FRAME_RATE) { ret = ERROR; free(dfps); goto splash_err; } pinfo->dfps = *dfps; free(dfps); splash_err: return ret; }
uint32_t mmc_write_protect(const char *ptn_name, int set_clr) { void *dev = NULL; struct mmc_card *card = NULL; uint32_t block_size; unsigned long long ptn = 0; uint64_t size; int index = -1; #ifdef UFS_SUPPORT int ret = 0; #endif dev = target_mmc_device(); block_size = mmc_get_device_blocksize(); if (target_mmc_device()) { card = &((struct mmc_device *)dev)->card; index = partition_get_index(ptn_name); ptn = partition_get_offset(index); if(!ptn) { return 1; } /* Convert the size to blocks */ size = partition_get_size(index) / block_size; /* * For read only partitions the minimum size allocated on the disk is * 1 WP GRP size. If the size of partition is less than 1 WP GRP size * protect atleast one WP group. */ if (partition_read_only(index) && size < card->wp_grp_size) { /* Write protect api takes the size in bytes, convert size to bytes */ size = card->wp_grp_size * block_size; } else { size *= block_size; } /* Set the power on WP bit */ return mmc_set_clr_power_on_wp_user((struct mmc_device *)dev, (ptn / block_size), size, set_clr); } else { #ifdef UFS_SUPPORT /* Enable the power on WP fo all LUNs which have WP bit is enabled */ ret = dme_set_fpoweronwpen((struct ufs_dev*) dev); if (ret < 0) { dprintf(CRITICAL, "Failure to WP UFS partition\n"); return 1; } #endif } return 0; }
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; }
BOOL cmd_flash_nand_img(const char *arg, void *data, unsigned sz) { int index; u64 offset,size; int img_type; char *p_type; char msg[256]; index = partition_get_index(arg); if(index == -1){ fastboot_fail_wrapper("partition get index fail"); return FALSE; } if(!is_support_flash(index)){ sprintf(msg,"partition '%s' not support flash\n",arg); fastboot_fail_wrapper(msg); return FALSE; } offset = partition_get_offset(index); if(offset == -1){ fastboot_fail_wrapper("partition get offset fail"); return FALSE; }else{ printf("get offset: 0x%llx\n",offset); } size = partition_get_size(index); if(size == -1){ fastboot_fail_wrapper("partition get size fail"); return FALSE; }else{ printf("get size: 0x%llx\n",size); } if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC))) { fastboot_fail_wrapper("image is not a boot image"); return FALSE; } } { char i_type[20] = {0}; get_image_type(data,sz,(char *)i_type); partition_get_type(index,&p_type); if(strcmp(i_type,p_type)){ display_info("[warning]image type is not match with partition type\n"); dprintf(DBG_LV, "[warning]image type'%s' is not match with partition type'%s'",i_type,p_type); } if(!strcmp(i_type,"raw data")){ img_type = RAW_DATA_IMG; }else if(!strcmp(i_type,"yaffs2")){ img_type = YFFS2_IMG; }else if(!strcmp(i_type,"ubifs")){ img_type = UBIFS_IMG; }else{ dprintf(DBG_LV, "image type '%s' unkown\n",i_type); display_info("\nimage type unkown"); return FALSE; } } TIME_START; display_info("write flash ...."); printf("writing %d bytes to '%s' img_type %d\n", sz, arg,img_type); if (nand_write_img((u32)offset, data, sz,(u32)size,img_type)) { fastboot_fail_wrapper("nand write image failure"); return FALSE; } printf("partition '%s' updated\n", arg); fastboot_ok_wrapper("write flash sucess",sz); return TRUE; }
BOOL cmd_flash_emmc_img(const char *arg, void *data, unsigned sz) { #ifdef MTK_NEW_COMBO_EMMC_SUPPORT unsigned int part_id; #endif unsigned long long ptn = 0; unsigned long long size = 0; unsigned long long size_wrote = 0; int index = INVALID_PTN; u32 pre_chksum = 0; u32 post_chksum = 0; char msg[256]; dprintf(DBG_LV, "Function cmd_flash_img()\n"); //dprintf(DBG_LV, "EMMC Offset[0x%x], Length[0x%x], data In[0x%x]\n", arg, sz, data); TIME_START; if (!strcmp(arg, "partition")) { dprintf(DBG_LV, "Attempt to write partition image.(MBR, GPT?)\n"); dprintf(DBG_LV, "Not supported, return.\n"); fastboot_fail_wrapper("Not supported 'partition'.\n"); return FALSE; /*if (write_partition(sz, (unsigned char *) data)) { fastboot_fail_wrapper("failed to write partition"); return FALSE; }*/ } else { index = partition_get_index(arg); if(index == -1) { fastboot_fail_wrapper("partition table doesn't exist"); return FALSE; } if(!is_support_flash(index)){ sprintf(msg,"\npartition '%s' not support flash",arg); fastboot_fail_wrapper(msg); return FALSE; } #ifdef MTK_NEW_COMBO_EMMC_SUPPORT part_id = partition_get_region(index); #endif ptn = partition_get_offset(index); //dprintf(DBG_LV, "[arg:%s]-[index:%d]-[ptn(offset):0x%x]\n", arg, index, ptn); if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC))) { fastboot_fail_wrapper("\nimage is not a boot image"); return FALSE; } } size = partition_get_size(index); //dprintf(DBG_LV, "[index:%d]-[partitionSize:%lld]-[downSize:%lld]\n", index, size, sz); if (ROUND_TO_PAGE(sz,511) > size) { fastboot_fail_wrapper("size too large"); dprintf(DBG_LV, "size too large"); return FALSE; } display_info("\nWriting Flash ... "); pre_chksum = calc_checksum(data, (u32)sz); #ifdef MTK_NEW_COMBO_EMMC_SUPPORT size_wrote = emmc_write(part_id, ptn , data, sz); #else size_wrote = emmc_write(ptn , data, sz); #endif if (size_wrote != sz) { //dprintf(DBG_LV, "emmc_write() Failed. act(%lld) != want(%lld)\n", size_wrote, sz); fastboot_fail_wrapper("\nFlash write failure"); return FALSE; } #ifdef MTK_NEW_COMBO_EMMC_SUPPORT if(sz != emmc_read(part_id, ptn, data, sz)) #else if(sz != emmc_read(ptn, data, sz)) #endif { dprintf(DBG_LV, "emmc_read() Failed.\n"); fastboot_fail_wrapper("\nRead EMMC error."); return FALSE; } post_chksum = calc_checksum(data, (u32)sz); if(post_chksum != pre_chksum) { dprintf(DBG_LV, "write_to_emmc() Failed. checksum error\n"); fastboot_fail_wrapper("\nChecksum Error."); return FALSE; } fastboot_ok_wrapper("OK", sz); } return TRUE; }
BOOL write_to_nand(u8* data, u32 length, u32 img_total_len) { static u64 partition_size = 0; int next_flip = 0; u32 index; static int img_type = UNKOWN_IMG; s8* p_type; u32 w_length =0; //u32 pre_chksum = 0; //u32 post_chksum = 0; int r; if(sto_info.first_run) { r = get_partition_name(data, length, sto_info.partition_name); if(r < 0) { display_info("\nGet_partition_name() Fail"); return FALSE; } index = partition_get_index(sto_info.partition_name); // if(index == -1) { display_info("\nBrick phone??"); return FALSE; } if(!is_support_flash(index)) { display_info("\nDont support partition."); return FALSE; } partition_size = partition_get_size(index); dprintf(DBG_LV, "[index:%d]-[partitionSize:%lld]-[downSize:%d]\n", index, partition_size, sto_info.to_write_data_len); if (ROUND_TO_PAGE(sto_info.to_write_data_len,511) > partition_size) { display_info("size too large, space small."); dprintf(DBG_LV, "size too large, space small."); return FALSE; } { char i_type[20] = {0}; get_image_type(data,length,(char *)i_type); partition_get_type(index,&p_type); if(strcmp(i_type,p_type)){ display_info("[warning]image type is not match with partition type\n"); dprintf(DBG_LV, "[warning]image type'%s' is not match with partition type'%s'",i_type,p_type); } printf("image type %s\n",i_type); if(!strcmp(i_type,"raw data")){ img_type = RAW_DATA_IMG; }else if(!strcmp(i_type,"yaffs2")){ img_type = YFFS2_IMG; }else if(!strcmp(i_type,"ubifs")){ img_type = UBIFS_IMG; }else{ dprintf(DBG_LV, "image type '%s' unkown\n",i_type); display_info("\nimage type unkown"); return FALSE; } } sto_info.image_base_addr = partition_get_offset(index); //NAND has no sparse image. //sto_info.unsparse_status.image_base_addr = sto_info.image_base_addr; //sto_info.is_sparse_image = is_sparse_image(data, length); sto_info.first_run = 0; } #if defined(MTK_MLC_NAND_SUPPORT) if (0 != nand_write_img_ex((u64)(sto_info.image_base_addr+sto_info.bulk_image_offset), (void*)data, length,img_total_len?(u64)(img_total_len):(u64)(sto_info.to_write_data_len), &w_length, (u64)(sto_info.image_base_addr),(u64)partition_size, img_type)) #else if (0 != nand_write_img_ex((u32)(sto_info.image_base_addr+sto_info.bulk_image_offset), (void*)data, length,img_total_len?(u32)(img_total_len):(u32)(sto_info.to_write_data_len), &w_length, (u32)(sto_info.image_base_addr),(u32)partition_size, img_type)) #endif { dprintf(DBG_LV, "nand_write_img() Failed.\n"); display_info("Error in write bulk in NAND."); return FALSE; } if(sto_info.checksum_enabled) { //NAND do not support read() now. } sto_info.bulk_image_offset += w_length; return TRUE; }
BOOL write_to_emmc(u8* data, u32 length) { u64 paritition_size = 0; u64 size_wrote = 0; int next_flip = 0; u32 index; u32 pre_chksum = 0; u32 post_chksum = 0; int r; while(sto_info.first_run) { r = get_partition_name(data, length, sto_info.partition_name); if(r < 0) { display_info("\nget_partition_name() Fail"); return FALSE; } if((!strncmp((char*)sto_info.partition_name, (char*)"signatureFile", 16)) || (!strncmp((char*)sto_info.partition_name, (char*)"boot", 8))) { //this do not need subsequent codes for normal partition. ctx.boot_like_info.is_boot_like_image = TRUE; ctx.boot_like_info.offset = 0; sto_info.first_run = 0; break; } index = partition_get_index((char*)sto_info.partition_name); if(index == (u32)(-1)) { display_info("\nBrick phone??"); return FALSE; } if(!is_support_flash(index)) { display_info((char*)sto_info.partition_name); display_info("\nDont support partition"); return FALSE; } paritition_size = partition_get_size(index); dprintf(DBG_LV, "[index:%d]-[downSize:%d]\n", index, sto_info.to_write_data_len); if (ROUND_TO_PAGE(sto_info.to_write_data_len,511) > paritition_size) { display_info("\nsize too large, space small."); dprintf(DBG_LV, "size too large, space small."); return FALSE; } #ifdef MTK_NEW_COMBO_EMMC_SUPPORT sto_info.part_id = partition_get_region(index); sto_info.unsparse_status.part_id = sto_info.part_id; #endif sto_info.image_base_addr = partition_get_offset(index); sto_info.unsparse_status.image_base_addr = sto_info.image_base_addr; sto_info.is_sparse_image = is_sparse_image(data, length); sto_info.first_run = 0; } //boot like image do not need write to image at this function. it is in flash function. if(ctx.boot_like_info.is_boot_like_image) { dprintf(DBG_LV, "boot like img: len: %d\n", length); dprintf(DBG_LV, "data: %08X\n", (u32)data); //dprintf(DBG_LV, "ctx.boot_like_info.boot_like_image_address: %08X, ctx.boot_like_info.offset %u, \n", ctx.boot_like_info.boot_like_image_address , ctx.boot_like_info.offset); memcpy(ctx.boot_like_info.boot_like_image_address + ctx.boot_like_info.offset, data, length); ctx.boot_like_info.offset += length; return TRUE; } if(sto_info.is_sparse_image) { next_flip = cache_shift(ctx.flipIdxR); sto_info.unsparse_status.buf = data; sto_info.unsparse_status.size = length; mmc_write_sparse_data(&sto_info.unsparse_status); if(sto_info.unsparse_status.handle_status == S_DA_SDMMC_SPARSE_INCOMPLETE) { ctx.dual_cache[next_flip].padding_length = sto_info.unsparse_status.size; memcpy(ctx.dual_cache[next_flip].padding_buf +(CACHE_PADDING_SIZE-sto_info.unsparse_status.size) , sto_info.unsparse_status.buf , sto_info.unsparse_status.size); } else if (sto_info.unsparse_status.handle_status== S_DONE) { ctx.dual_cache[next_flip].padding_length = 0; } else { //some error dprintf(DBG_LV, "write_to_emmc() Failed. handle_status(%d)\n", sto_info.unsparse_status.handle_status); display_info("\nError in write sparse image in EMMC."); return FALSE; } } else { #ifdef MTK_NEW_COMBO_EMMC_SUPPORT size_wrote = emmc_write(sto_info.part_id, sto_info.image_base_addr+sto_info.bulk_image_offset , (void*)data, length); #else size_wrote = emmc_write(sto_info.image_base_addr+sto_info.bulk_image_offset , (void*)data, length); #endif if (size_wrote != length) { dprintf(DBG_LV, "write_to_emmc() Failed. act(%d) != want(%d)\n", (u32)size_wrote, length); display_info("\nError in write bulk in EMMC."); return FALSE; } if(sto_info.checksum_enabled) { pre_chksum = calc_checksum(data, (u32)length); #ifdef MTK_NEW_COMBO_EMMC_SUPPORT if(length != emmc_read(sto_info.part_id, sto_info.image_base_addr+sto_info.bulk_image_offset, data, length)) #else if(length != emmc_read(sto_info.image_base_addr+sto_info.bulk_image_offset, data, length)) #endif { dprintf(DBG_LV, "emmc_read() Failed.\n"); display_info("\nError in Read bulk EMMC."); return FALSE; } post_chksum = calc_checksum(data, (u32)length); if(post_chksum != pre_chksum) { dprintf(DBG_LV, "write_to_emmc() Failed. checksum error\n"); display_info("\nWrite bulk in EMMC. Checksum Error"); return FALSE; } } sto_info.bulk_image_offset += size_wrote; } return TRUE; }
BOOL cmd_flash_emmc_sparse_img(const char *arg, void *data, unsigned sz) { unsigned int chunk; unsigned int chunk_data_sz; sparse_header_t *sparse_header; chunk_header_t *chunk_header; u32 total_blocks = 0; #ifdef MTK_NEW_COMBO_EMMC_SUPPORT unsigned int part_id; #endif unsigned long long ptn = 0; unsigned long long size = 0; unsigned long long size_wrote = 0; int index = INVALID_PTN; char msg[256]; dprintf(DBG_LV, "Enter cmd_flash_sparse_img()\n"); //dprintf(DBG_LV, "EMMC Offset[0x%x], Length[%d], data In[0x%x]\n", arg, sz, data); index = partition_get_index(arg); if(index == -1) { fastboot_fail_wrapper("partition table doesn't exist"); return FALSE; } if(!is_support_flash(index)){ sprintf(msg,"partition '%s' not support flash\n",arg); fastboot_fail_wrapper(msg); return FALSE; } #ifdef MTK_NEW_COMBO_EMMC_SUPPORT part_id = partition_get_region(index); #endif ptn = partition_get_offset(index); size = partition_get_size(index); if (ROUND_TO_PAGE(sz,511) > size) { fastboot_fail_wrapper("size too large"); return FALSE; } /* Read and skip over sparse image header */ sparse_header = (sparse_header_t *) data; data += sparse_header->file_hdr_sz; if(sparse_header->file_hdr_sz > sizeof(sparse_header_t)) { /* Skip the remaining bytes in a header that is longer than * we expected. */ data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t)); } dprintf (DBG_LV, "=== Sparse Image Header ===\n"); dprintf (DBG_LV, "magic: 0x%x\n", sparse_header->magic); dprintf (DBG_LV, "major_version: 0x%x\n", sparse_header->major_version); dprintf (DBG_LV, "minor_version: 0x%x\n", sparse_header->minor_version); dprintf (DBG_LV, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz); dprintf (DBG_LV, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz); dprintf (DBG_LV, "blk_sz: %d\n", sparse_header->blk_sz); dprintf (DBG_LV, "total_blks: %d\n", sparse_header->total_blks); dprintf (DBG_LV, "total_chunks: %d\n", sparse_header->total_chunks); TIME_START; display_info("Writing Flash ... "); /* Start processing chunks */ for (chunk=0; chunk<sparse_header->total_chunks; chunk++) { /* Read and skip over chunk header */ chunk_header = (chunk_header_t *) data; data += sizeof(chunk_header_t); dprintf (INFO, "=== Chunk Header ===\n"); dprintf (INFO, "chunk_type: 0x%x\n", chunk_header->chunk_type); dprintf (INFO, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz); dprintf (INFO, "total_size: 0x%x\n", chunk_header->total_sz); if(sparse_header->chunk_hdr_sz > sizeof(chunk_header_t)) { /* Skip the remaining bytes in a header that is longer than * we expected. */ data += (sparse_header->chunk_hdr_sz - sizeof(chunk_header_t)); } chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz; switch (chunk_header->chunk_type) { case CHUNK_TYPE_RAW: if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz + chunk_data_sz)) { fastboot_fail_wrapper("Bogus chunk size for chunk type Raw"); return FALSE; } //dprintf(INFO, "[Flash Base Address:0x%llx offset:0x%llx]-[size:%d]-[DRAM Address:0x%x]\n", // ptn , ((uint64_t)total_blocks*sparse_header->blk_sz), chunk_data_sz, data); #ifdef MTK_NEW_COMBO_EMMC_SUPPORT size_wrote = emmc_write(part_id, ptn + ((uint64_t)total_blocks*sparse_header->blk_sz), (unsigned int*)data, chunk_data_sz); #else size_wrote = emmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz), (unsigned int*)data, chunk_data_sz); #endif dprintf(INFO, "[wrote:%lld]-[size:%d]\n", size_wrote ,chunk_data_sz); if(size_wrote != chunk_data_sz) { fastboot_fail_wrapper("flash write failure"); return FALSE; } total_blocks += chunk_header->chunk_sz; data += chunk_data_sz; break; case CHUNK_TYPE_DONT_CARE: total_blocks += chunk_header->chunk_sz; break; case CHUNK_TYPE_CRC: if(chunk_header->total_sz != sparse_header->chunk_hdr_sz) { fastboot_fail_wrapper("Bogus chunk size for chunk type Dont Care"); return FALSE; } total_blocks += chunk_header->chunk_sz; data += chunk_data_sz; break; default: fastboot_fail_wrapper("Unknown chunk type"); return FALSE; } } dprintf(DBG_LV, "Wrote %d blocks, expected to write %d blocks\n", total_blocks, sparse_header->total_blks); if(total_blocks != sparse_header->total_blks) { fastboot_fail_wrapper("sparse image write failure"); return FALSE; } fastboot_ok_wrapper("Write Flash OK", sz); return TRUE;; }
BOOL cmd_flash_nand_img(const char *arg, void *data, unsigned sz) { int index; u64 offset,size; int img_type; char *p_type; char msg[256]; index = partition_get_index(arg); if(index == -1){ fastboot_fail_wrapper("partition get index fail"); return FALSE; } if(!is_support_flash(index)){ sprintf(msg,"partition '%s' not support flash\n",arg); fastboot_fail_wrapper(msg); return FALSE; } offset = partition_get_offset(index); if(offset == (u64)(-1)){ fastboot_fail_wrapper("partition get offset fail"); return FALSE; }else{ printf("get offset: 0x%llx\n",offset); } size = partition_get_size(index); if(size == (u64)(-1)){ fastboot_fail_wrapper("partition get size fail"); return FALSE; }else{ printf("get size: 0x%llx\n",size); } if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC))) { fastboot_fail_wrapper("image is not a boot image"); return FALSE; } } { char i_type[20] = {0}; get_image_type(data,sz,(char *)i_type); partition_get_type(index,&p_type); if(strcmp(i_type,p_type)){ display_info("[warning]image type is not match with partition type\n"); dprintf(DBG_LV, "[warning]image type'%s' is not match with partition type'%s'",i_type,p_type); } if(!strcmp(i_type,"raw data")){ img_type = RAW_DATA_IMG; }else if(!strcmp(i_type,"yaffs2")){ img_type = YFFS2_IMG; }else if(!strcmp(i_type,"ubifs")){ img_type = UBIFS_IMG; }else{ dprintf(DBG_LV, "image type '%s' unkown\n",i_type); display_info("\nimage type unkown"); return FALSE; } } TIME_START; display_info("write flash ...."); printf("writing %d bytes to '%s' img_type %d\n", sz, arg,img_type); #if defined(MTK_MLC_NAND_SUPPORT) if (nand_write_img((u64)offset, (char*)data, sz,(u64)size,img_type)) { #else if (nand_write_img((u32)offset, (char*)data, sz,(u32)size,img_type)) { #endif fastboot_fail_wrapper("nand write image failure"); return FALSE; } printf("partition '%s' updated\n", arg); fastboot_ok_wrapper("write flash sucess",sz); return TRUE; } void cmd_flash_nand(const char *arg, void *data, unsigned sz) { char msg[128] = {0}; if(sz == 0) { fastboot_okay(""); return; } #ifdef MTK_SECURITY_SW_SUPPORT //Please DO NOT get any data for reference if security check is not passed if(!security_check((u8**)&data, &sz, 0, arg)) { sprintf(msg, "\nSecurity deny - Err:0x%x \n", sec_error()); dprintf(DBG_LV, msg); fastboot_fail_wrapper(msg); return; } #endif dprintf(DBG_LV, "cmd_flash_nand, data:0x%x\n",*(int*)data); if(cmd_flash_nand_img(arg,data,sz)) { //[Security] Notify security check that is the end. sz = 0; #ifdef MTK_SECURITY_SW_SUPPORT security_check((u8**)&data, &sz, IMAGE_TRUNK_SIZE, arg); #endif } }
BOOL write_to_emmc(u8* data, u32 length) { u64 paritition_size = 0; u64 size_wrote = 0; int next_flip = 0; u32 index; u32 pre_chksum = 0; u32 post_chksum = 0; int r; if(sto_info.first_run) { r = get_partition_name(data, length, sto_info.partition_name); if(r < 0) { display_info("\nASSERT!! get_partition_name() Fail"); return FALSE; } if(!strncmp(sto_info.partition_name, "boot", 8)) { ctx.boot_info.is_boot_image = TRUE; ctx.boot_info.offset = 0; } index = partition_get_index(sto_info.partition_name); if(index == -1) { display_info("\nASSERT!! Brick phone??"); return FALSE; } if(!is_support_flash(index)) { display_info(sto_info.partition_name); display_info("\nASSERT!! Dont support system??"); return FALSE; } paritition_size = partition_get_size(index); dprintf(DBG_LV, "[index:%d]-[partitionSize:%lld]-[downSize:%lld]\n", index, paritition_size, sto_info.to_write_data_len); if (ROUND_TO_PAGE(sto_info.to_write_data_len,511) > paritition_size) { display_info("\nsize too large, space small."); dprintf(DBG_LV, "size too large, space small."); return FALSE; } sto_info.image_base_addr = partition_get_offset(index); sto_info.unsparse_status.image_base_addr = sto_info.image_base_addr; sto_info.is_sparse_image = is_sparse_image(data, length); sto_info.first_run = 0; } //boot image do not need write to image at this function. it is in flash function. if(ctx.boot_info.is_boot_image) { dprintf(DBG_LV, "boot img: len: %d\n", length); dprintf(DBG_LV, "data: %08X\n", data); dprintf(DBG_LV, "ctx.boot_info.boot_image_address: %08X, ctx.boot_info.offset %u, \n", ctx.boot_info.boot_image_address , ctx.boot_info.offset); memcpy(ctx.boot_info.boot_image_address + ctx.boot_info.offset, data, length); ctx.boot_info.offset += length; return TRUE; } if(sto_info.is_sparse_image) { next_flip = cache_shift(ctx.flipIdxR); sto_info.unsparse_status.buf = data; sto_info.unsparse_status.size = length; mmc_write_sparse_data(&sto_info.unsparse_status); if(sto_info.unsparse_status.handle_status == S_DA_SDMMC_SPARSE_INCOMPLETE) { ctx.dual_cache[next_flip].padding_length = sto_info.unsparse_status.size; memcpy(ctx.dual_cache[next_flip].padding_buf +(CACHE_PADDING_SIZE-sto_info.unsparse_status.size) , sto_info.unsparse_status.buf , sto_info.unsparse_status.size); } else if (sto_info.unsparse_status.handle_status== S_DONE) { ctx.dual_cache[next_flip].padding_length = 0; } else { //some error dprintf(DBG_LV, "write_to_emmc() Failed. handle_status(%d)\n", sto_info.unsparse_status.handle_status); display_info("\nError in write sparse image in EMMC."); return FALSE; } } else { size_wrote = emmc_write(sto_info.image_base_addr+sto_info.bulk_image_offset , (void*)data, length); if (size_wrote != length) { dprintf(DBG_LV, "write_to_emmc() Failed. act(%lld) != want(%lld)\n", size_wrote, length); display_info("\nError in write bulk in EMMC."); return FALSE; } if(sto_info.checksum_enabled) { pre_chksum = calc_checksum(data, (u32)length); if(length != emmc_read(sto_info.image_base_addr+sto_info.bulk_image_offset, data, length)) { dprintf(DBG_LV, "emmc_read() Failed.\n"); display_info("\nError in Read bulk EMMC."); return FALSE; } post_chksum = calc_checksum(data, (u32)length); if(post_chksum != pre_chksum) { dprintf(DBG_LV, "write_to_emmc() Failed. checksum error\n"); display_info("\nWrite bulk in EMMC. Checksum Error"); return FALSE; } } sto_info.bulk_image_offset += size_wrote; } return TRUE; }