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