Esempio n. 1
0
File: grub.c Progetto: sndnvaps/lk-1
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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
File: init.c Progetto: jbott/lk_gee
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);
}
Esempio n. 4
0
/**
 * 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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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;
}
Esempio n. 16
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;
}
Esempio n. 17
0
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;
}
Esempio n. 19
0
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;
}
Esempio n. 20
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;
}
Esempio n. 21
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
    }
}
Esempio n. 27
0
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;
}