Пример #1
0
void fb_mmc_erase(const char *cmd, char *response)
{
	int ret;
	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;
	}

	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;
	}

	erase_image(dev_desc, &info, cmd);
}
Пример #2
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);
}
Пример #3
0
int do_mrvlboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char cmd[128];
	char cmdline[COMMAND_LINE_SIZE];
	char *bootargs;
	unsigned int kernel_offset = 0, ramdisk_offset = KERNEL_SIZE;
	unsigned int kernel_size = KERNEL_SIZE, ramdisk_size = RAMDISK_SIZE;
	unsigned long base_emmc_addr, kernel_load_addr, ramdisk_load_addr;
	int recovery_flag = 0;
	int fastboot_flag = 0;
#ifdef CONFIG_OF_LIBFDT
	unsigned long dtb_load_addr, dtb_emmc_addr;
	struct fdt_header *devtree;
#endif
#ifdef CONFIG_MULTIPLE_SLOTS
	int slot;
#endif
        block_dev_desc_t *dev;
        disk_partition_t info;
        unsigned long recovery_image_addr;

	/* The bootimg/recoveryimg header + uImage header ddr parse address */
	struct andr_img_hdr *ahdr =
		(struct andr_img_hdr *)(CONFIG_LOADADDR - 0x1000 - 0x200);

	recovery_flag = get_recovery_flag();
	fastboot_flag = fastboot_key_detect();

        dev = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
        if(!dev){
                printf("Failed to get mmc device!\n");
                return -1;
        }
        /*Parse flash address from the partition name*/ 
        if (get_partition_info_efi_by_name(dev, "recovery", &info)){
                printf("Failed to get partition(recovery) info!\n");
                return -1;
        }
        recovery_image_addr = info.start * dev->blksz;

	/*
	 * OBM doesn't load kernel and ramdisk for nontrusted boot, but it
	 * still passes validation_status and loading_status as 1 to uboot
	 * since uboot is loaded and validated.
	 * Always load the kernel and ramdisk here to solve this problem,
	 * negative impact of a little boot time.
	 */
#ifdef CONFIG_MULTIPLE_SLOTS
	slot = bootctrl_find_boot_slot();
	if (slot == -1)
		recovery_flag = 1;

	base_emmc_addr = recovery_flag ? recovery_image_addr :
							bootctrl_get_boot_addr(slot);
#else
        if(get_partition_info_efi_by_name(dev, "boot", &info)){
                printf("Failed to get partition(boot) info!\n");
                return -1;
        }
        unsigned long boot_image_addr = info.start * dev->blksz;

	base_emmc_addr = recovery_flag ? recovery_image_addr : boot_image_addr;
#endif

	load_image_head(ahdr, base_emmc_addr);

	if (!memcmp(ANDR_BOOT_MAGIC, ahdr->magic, ANDR_BOOT_MAGIC_SIZE)) {
		printf("This is Android %s image\n",
		       recovery_flag ? "recovery" : "boot");
		kernel_offset = ahdr->page_size;
		kernel_size = ALIGN(ahdr->kernel_size, ahdr->page_size);
		ramdisk_offset = kernel_offset + kernel_size;
		ramdisk_size = ALIGN(ahdr->ramdisk_size, ahdr->page_size);
	}
	/* calculate mmc block number */
	kernel_offset /= dev->blksz;
	ramdisk_offset /= dev->blksz;
	kernel_size /= dev->blksz;
	ramdisk_size /= dev->blksz;

	/* Load kernel */
	kernel_load_addr = CONFIG_LOADADDR;
	if ((load_op & MV_KERNEL_LOADED) == 0) {
		printf("Load kernel to 0x%lx\n", kernel_load_addr);
		sprintf(cmd, "mmc read %lx %lx %x", kernel_load_addr,
			base_emmc_addr / 512 + kernel_offset, kernel_size);
		run_command(cmd, 0);
	}

	/* Load ramdisk */
	ramdisk_load_addr = RAMDISK_LOADADDR;
	if ((load_op & MV_RAMDISK_LOADED) == 0) {
		printf("Load ramdisk to 0x%lx\n", ramdisk_load_addr);
		sprintf(cmd, "mmc read %lx %lx %x", ramdisk_load_addr,
			base_emmc_addr / 512 + ramdisk_offset, ramdisk_size);
		run_command(cmd, 0);
	}

	/* Modify ramdisk command line */
	bootargs = getenv("bootargs");
	strncpy(cmdline, bootargs, COMMAND_LINE_SIZE);
	remove_cmdline_param(cmdline, "initrd=");
	sprintf(cmdline + strlen(cmdline),  " initrd=0x%lx,10m rw",
		ramdisk_load_addr);

	if (recovery_flag)
		sprintf(cmdline + strlen(cmdline), " recovery=1");

#ifdef CONFIG_MULTIPLE_SLOTS
	if(slot >= 0)
		sprintf(cmdline + strlen(cmdline), " androidboot.slot_suffix=%s",
				bootctrl_get_boot_slot_suffix(slot));
#endif

	setenv("bootargs", cmdline);

#ifdef CONFIG_OF_LIBFDT
	/* Load DTB */
	dtb_load_addr = DTB_LOADADDR;
	if ((load_op & MV_DTB_LOADED) == 0) {
		dtb_emmc_addr = dtb_emmc_lookup(ahdr, base_emmc_addr);
		printf("Load dtb to 0x%lx\n", dtb_load_addr);
		sprintf(cmd, "mmc read %lx %lx %x", dtb_load_addr,
			dtb_emmc_addr / 512, DTB_SIZE / 512);
		run_command(cmd, 0);
	}

	devtree = (struct fdt_header *)dtb_load_addr;
	if (be32_to_cpu(devtree->magic) == FDT_MAGIC) {
		handle_dtb(devtree);
		sprintf(cmd, "fdt addr 0x%lx; bootm 0x%lx - 0x%lx",
			dtb_load_addr, kernel_load_addr, dtb_load_addr);
	} else
#endif
//#if !defined(CONFIG_CMD_BOOTZ) || defined(CONFIG_OF_LIBFDT)
#ifndef CONFIG_BOOTZIMAGE
 		sprintf(cmd, "bootm 0x%lx", kernel_load_addr);
#else
		/* zImage-dtb option */
		sprintf(cmd, "bootz 0x%lx", kernel_load_addr);
#endif

	if (fastboot_flag) {
		printf("mrvlboot, fastboot mode\n");
		fastboot_key_set_led();
		run_command("fb", 0);
		return 0;
	} else
		printf("mrvlboot, normal mode\n");

	run_command(cmd, 0);

	return 0;
}
Пример #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);
	}
}