Esempio n. 1
0
void fb_mmc_flash_write(const char *cmd, void *download_buffer,
			unsigned int download_bytes)
{
	struct blk_desc *dev_desc;
	disk_partition_t info;

	dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
		error("invalid mmc device\n");
		fastboot_fail("invalid mmc device");
		return;
	}

	if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
		printf("%s: updating MBR, Primary and Backup GPT(s)\n",
		       __func__);
		if (is_valid_gpt_buf(dev_desc, download_buffer)) {
			printf("%s: invalid GPT - refusing to write to flash\n",
			       __func__);
			fastboot_fail("invalid GPT partition");
			return;
		}
		if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
			printf("%s: writing GPT partitions failed\n", __func__);
			fastboot_fail(
				      "writing GPT partitions failed");
			return;
		}
		printf("........ success\n");
		fastboot_okay("");
		return;
	} else if (part_get_info_efi_by_name_or_alias(dev_desc, cmd, &info)) {
		error("cannot find partition: '%s'\n", cmd);
		fastboot_fail("cannot find partition");
		return;
	}

	if (is_sparse_image(download_buffer)) {
		struct fb_mmc_sparse sparse_priv;
		struct sparse_storage sparse;

		sparse_priv.dev_desc = dev_desc;

		sparse.blksz = info.blksz;
		sparse.start = info.start;
		sparse.size = info.size;
		sparse.write = fb_mmc_sparse_write;
		sparse.reserve = fb_mmc_sparse_reserve;

		printf("Flashing sparse image at offset " LBAFU "\n",
		       sparse.start);

		sparse.priv = &sparse_priv;
		write_sparse_image(&sparse, cmd, download_buffer,
				   download_bytes);
	} else {
		write_raw_image(dev_desc, &info, cmd, download_buffer,
				download_bytes);
	}
}
Esempio n. 2
0
void fb_nand_flash_write(const char *cmd, void *download_buffer,
			 unsigned int download_bytes)
{
	struct part_info *part;
	struct mtd_info *mtd = NULL;
	int ret;

	ret = fb_nand_lookup(cmd, &mtd, &part);
	if (ret) {
		error("invalid NAND device");
		fastboot_fail("invalid NAND device");
		return;
	}

	ret = board_fastboot_write_partition_setup(part->name);
	if (ret)
		return;

	if (is_sparse_image(download_buffer)) {
		struct fb_nand_sparse sparse_priv;
		struct sparse_storage sparse;

		sparse_priv.mtd = mtd;
		sparse_priv.part = part;

		sparse.blksz = mtd->writesize;
		sparse.start = part->offset / sparse.blksz;
		sparse.size = part->size / sparse.blksz;
		sparse.write = fb_nand_sparse_write;
		sparse.reserve = fb_nand_sparse_reserve;

		printf("Flashing sparse image at offset " LBAFU "\n",
		       sparse.start);

		sparse.priv = &sparse_priv;
		write_sparse_image(&sparse, cmd, download_buffer,
				   download_bytes);
	} else {
		printf("Flashing raw image at offset 0x%llx\n",
		       part->offset);

		ret = _fb_nand_write(mtd, part, download_buffer, part->offset,
				     download_bytes, NULL);

		printf("........ wrote %u bytes to '%s'\n",
		       download_bytes, part->name);
	}

	if (ret) {
		fastboot_fail("error writing the image");
		return;
	}

	fastboot_okay("");
}
Esempio n. 3
0
void fb_mmc_flash_write(const char *cmd, void *download_buffer,
			unsigned int download_bytes, char *response)
{
	block_dev_desc_t *dev_desc;
	disk_partition_t info;

	/* initialize the response buffer */
	response_str = response;

	dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
		error("invalid mmc device\n");
		fastboot_fail("invalid mmc device");
		return;
	}

	if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
		printf("%s: updating MBR, Primary and Backup GPT(s)\n",
		       __func__);
		if (is_valid_gpt_buf(dev_desc, download_buffer)) {
			printf("%s: invalid GPT - refusing to write to flash\n",
			       __func__);
			fastboot_fail("invalid GPT partition");
			return;
		}
		if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
			printf("%s: writing GPT partitions failed\n", __func__);
			fastboot_fail("writing GPT partitions failed");
			return;
		}
		printf("........ success\n");
		fastboot_okay("");
		return;
	} else if (get_partition_info_efi_by_name(dev_desc, cmd, &info)) {
		error("cannot find partition: '%s'\n", cmd);
		fastboot_fail("cannot find partition");
		return;
	}

	if (is_sparse_image(download_buffer))
		write_sparse_image(dev_desc, &info, cmd, download_buffer,
				   download_bytes);
	else
		write_raw_image(dev_desc, &info, cmd, download_buffer,
				download_bytes);
}
Esempio n. 4
0
void fb_mmc_flash_write(const char *cmd, void *download_buffer,
			unsigned int download_bytes, char *response)
{
	int ret;
        int expected;
        int pte_blk_cnt;

	block_dev_desc_t *dev_desc;
	disk_partition_t info;

	/* initialize the response buffer */
	response_str = response;

	legacy_mbr *mbr;
	gpt_header *primary_gpt_h;
        gpt_entry *second_gpt_e;

	dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
		error("invalid mmc device\n");
		fastboot_fail("invalid mmc device");
		return;
	}

#if 0
	char cmd_buf[64] = {0};

	ulong mmc_part;
	ulong mmc_flash_start;

	if (!strncmp("to:", cmd, strlen("to:"))) {
		strsep(&cmd, ":");
		if (!cmd) {
			error("missing variable\n");
			fastboot_fail("missing var");
			return;
		}
		mmc_part = simple_strtoul(cmd, NULL, 10);
		if(mmc_part > 16){
			error("Part # is too large\n");
			fastboot_fail("Part # is too large");
			return;
		}
		
		strsep(&cmd, ":");
		if (!cmd) {
			error("missing variable\n");
			fastboot_fail("missing var");
			return;
		}
		mmc_flash_start = simple_strtoul(cmd, NULL, 16);
		
		if(mmc_flash_start != PAD_TO_BLOCKSIZE(mmc_flash_start, dev_desc)){
			error("Offset must start from block size boudry\n");
			fastboot_fail("Offset must start from block size boudry");
			return;
		}

		sprintf(cmd_buf, "mmc dev %d %d", CONFIG_FASTBOOT_FLASH_MMC_DEV, mmc_part);
		run_command(cmd_buf, 0);

		if(dev_desc->lba != 0){
			if (dev_desc->block_write(dev_desc->dev, mmc_flash_start/dev_desc->blksz, BLOCK_CNT(download_bytes, dev_desc), download_buffer) != BLOCK_CNT(download_bytes, dev_desc)){
				error("flash data failed:\n");
				fastboot_fail("flash data failed:");
			}else{
				fastboot_okay("");
			}
		}else{
			error("Invalid mmc part\n");
			fastboot_fail("Invalid mmc part");
		}

		/* switch back to main part */
		sprintf(cmd_buf, "mmc dev %d 0", CONFIG_FASTBOOT_FLASH_MMC_DEV);
		run_command(cmd_buf, 0);
	}else 
#endif
	if (!strncmp("partition", cmd, strlen("partition"))) {
                /*do sanity check of the downloader data */
                expected = sizeof(legacy_mbr) + 2 * ((PAD_TO_BLOCKSIZE(sizeof(gpt_header), dev_desc) + PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS
                                               * sizeof(gpt_entry), dev_desc)));
                
		if(expected != download_bytes){
			error("wrong size for download data, expected: %d\n", expected);
			fastboot_fail("wrong size for download data");
			return;
		}

		mbr = download_buffer;
		primary_gpt_h = (void *)mbr + sizeof(legacy_mbr);
                pte_blk_cnt = BLOCK_CNT((primary_gpt_h->num_partition_entries * sizeof(gpt_entry)), dev_desc);
                second_gpt_e = primary_gpt_h + PAD_TO_BLOCKSIZE(sizeof(gpt_header), dev_desc)
                                             + PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry), dev_desc);

		/* Check the MBR signature */
		if (le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE){
			error("MBR signature is wrong:" 
                                "0x%X != 0x%X\n",
				le16_to_cpu(mbr->signature),
				MSDOS_MBR_SIGNATURE);
			fastboot_fail("wrong data");
			return;
		}

		/* Check the GPT header signature */
		if (le64_to_cpu(primary_gpt_h->signature) != GPT_HEADER_SIGNATURE) {
			error("GUID Partition Table Header signature is wrong:"
				"0x%llX != 0x%llX\n",
				le64_to_cpu(primary_gpt_h->signature),
				GPT_HEADER_SIGNATURE);
			fastboot_fail("wrong data");
			return;
		}

		/* Write the Legacy MBR */
		if (dev_desc->block_write(dev_desc->dev, 0, 1, mbr) != 1){
                        printf("Write mbr failed!\n");
                        goto err;
                }

		/* Write the First GPT to the block right after the Legacy MBR */
		if (dev_desc->block_write(dev_desc->dev, 1, pte_blk_cnt + 1, primary_gpt_h) != pte_blk_cnt + 1){
                        printf("Write primary gpt failed!\n");
                        goto err;
                }
               
                /*Write the Second GPT at the end of the block*/
                lbaint_t second_gpt_offset = le32_to_cpu(primary_gpt_h->last_usable_lba + 1);
                if(dev_desc->block_write(dev_desc->dev, second_gpt_offset,
                                         pte_blk_cnt + 1, second_gpt_e) != pte_blk_cnt + 1){
                       printf("write second gpt  failed!\n");
                       goto err;
                }
   
#if 0
		/* do sanity check of the download data */
		expected = sizeof(legacy_mbr)+ 1 * (PAD_TO_BLOCKSIZE(sizeof(gpt_header), dev_desc)+PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS
					       * sizeof(gpt_entry), dev_desc));
		/*if(expected != download_bytes){
			error("wrong size for download data, expected: %d\n", expected);
			fastboot_fail("wrong size for download data");
			return;
		}*/
                printf("legacy_mbr is %d, gpt_header is %d, gpt_entry is %d\n",sizeof(legacy_mbr),PAD_TO_BLOCKSIZE(sizeof(gpt_header), 
                                    dev_desc),PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry), dev_desc));
                 
		mbr = download_buffer;
		gpt_h = (void *)mbr + sizeof(legacy_mbr);
		gpt_e = (void *)gpt_h+PAD_TO_BLOCKSIZE(sizeof(gpt_header), dev_desc);

		/* Check the MBR signature */
		if (le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE){
			error("MBR signature is wrong:"
				"0x%X != 0x%X\n",
				le16_to_cpu(mbr->signature),
				MSDOS_MBR_SIGNATURE);
			fastboot_fail("wrong data");
			return;
		}

		/* Check the GPT header signature */
		if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE) {
			error("GUID Partition Table Header signature is wrong:"
				"0x%llX != 0x%llX\n",
				le64_to_cpu(gpt_h->signature),
				GPT_HEADER_SIGNATURE);
			fastboot_fail("wrong data");
			return;
		}
	
		const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
					   * sizeof(gpt_entry)), dev_desc);
		u32 calc_crc32;
		u64 val;

		printf("max lba: %x\n", (u32) dev_desc->lba);

                printf("last_usable_lba is %d, my_lba is %d, pte_blk_cnt is %d\n",le32_to_cpu(gpt_h->last_usable_lba + 1),le32_to_cpu(gpt_h->my_lba),
                        pte_blk_cnt);
		/* Write the Legacy MBR */
		if (dev_desc->block_write(dev_desc->dev, 0, 1, mbr) != 1){
			printf("Write mbr failed!\n");
			goto err;
                }
                printf("last_usable_lba is %d, my_lba is %d, pte_blk_cnt is %d\n",le32_to_cpu(gpt_h->last_usable_lba + 1),le32_to_cpu(gpt_h->my_lba),
                        pte_blk_cnt);

		/* Write the First GPT to the block right after the Legacy MBR */
		if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1){
                        printf("Write gpt header failed!\n");
			goto err;
                }
                printf("last_usable_lba is %d, my_lba is %d, pte_blk_cnt is %d\n",le32_to_cpu(gpt_h->last_usable_lba + 1),le32_to_cpu(gpt_h->my_lba),
                        pte_blk_cnt);

		if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e)
		    != pte_blk_cnt){
                        printf("Write gpt_e failed!\n");
			goto err;
                 }
                printf("last_usable_lba is %d, my_lba is %d, pte_blk_cnt is %d\n",le32_to_cpu(gpt_h->last_usable_lba + 1),le32_to_cpu(gpt_h->my_lba),
                        pte_blk_cnt);

		/* recalculate the values for the Second GPT Header */
                printf("last_usable_lba is %d, my_lba is %d, pte_blk_cnt is %d\n",le32_to_cpu(gpt_h->last_usable_lba + 1),le32_to_cpu(gpt_h->my_lba),
                        pte_blk_cnt);
		val = le64_to_cpu(gpt_h->my_lba);
		gpt_h->my_lba = gpt_h->alternate_lba;
		gpt_h->alternate_lba = cpu_to_le64(val);
		gpt_h->header_crc32 = 0;

		calc_crc32 = crc32(0, (const unsigned char *)gpt_h,
				      le32_to_cpu(gpt_h->header_size));
		gpt_h->header_crc32 = cpu_to_le32(calc_crc32);

                printf("last_usable_lba is %d, my_lba is %d, pte_blk_cnt is %d\n",le32_to_cpu(gpt_h->last_usable_lba + 1),le32_to_cpu(gpt_h->my_lba),
                        pte_blk_cnt);
 
		if (dev_desc->block_write(dev_desc->dev,
					  le32_to_cpu(gpt_h->last_usable_lba + 1),
					  pte_blk_cnt, gpt_e) != pte_blk_cnt){
			printf("Write second gpt_e failed!\n");
                        goto err;
                }

		if (dev_desc->block_write(dev_desc->dev,
					  le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1){
                        printf("Write second gpt_h failed!\n");
			goto err;
                }
#endif
		printf("GPT successfully written to block device!\n");
		fastboot_okay("");
		return;

	 err:
		error("flash partition data failed: '%s'\n", cmd);
		fastboot_fail("cannot flash partition");
		return;

	}else{

		ret = get_partition_info_efi_by_name(dev_desc, cmd, &info);
		if (ret) {
			error("cannot find partition: '%s'\n", cmd);
			fastboot_fail("cannot find partition");
			return;
		}

		if (is_sparse_image(download_buffer))
			write_sparse_image(dev_desc, &info, cmd, download_buffer,
					   download_bytes);
		else
			write_raw_image(dev_desc, &info, cmd, download_buffer,
					download_bytes);
	}
}