void fb_nand_erase(const char *partname, char *response) { struct part_info *part; nand_info_t *nand = NULL; int ret; /* initialize the response buffer */ response_str = response; ret = fb_nand_lookup(partname, response, &nand, &part); if (ret) { error("invalid NAND device"); fastboot_fail(response_str, "invalid NAND device"); return; } ret = board_fastboot_erase_partition_setup(part->name); if (ret) return; ret = _fb_nand_erase(nand, part); if (ret) { error("failed erasing from device %s", nand->name); fastboot_fail(response_str, "failed erasing from device"); return; } fastboot_okay(response_str, ""); }
void cmd_flash(const char *arg, void *data, unsigned sz) { struct ptentry *ptn; struct ptable *ptable; unsigned extra = 0; ptable = flash_get_ptable(); if (ptable == NULL) { fastboot_fail("partition table doesn't exist"); return; } ptn = ptable_find(ptable, arg); if (ptn == NULL) { fastboot_fail("unknown partition name"); return; } if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { fastboot_fail("image is not a boot image"); return; } } if (!strcmp(ptn->name, "system") || !strcmp(ptn->name, "userdata") || !strcmp(ptn->name, "persist")) extra = ((page_size >> 9) * 16); else
static void cmd_erase(struct protocol_handle *phandle, const char *arg) { int partition_fd; char path[PATH_MAX]; D(DEBUG, "cmd_erase %s\n", arg); if (flash_find_entry(arg, path, PATH_MAX)) { fastboot_fail(phandle, "partition table doesn't exist"); return; } if (path == NULL) { fastboot_fail(phandle, "Couldn't find partition"); return; } partition_fd = flash_get_partiton(path); if (partition_fd < 0) { fastboot_fail(phandle, "partiton file does not exists"); } if (flash_erase(partition_fd)) { fastboot_fail(phandle, "failed to erase partition"); flash_close(partition_fd); return; } if (flash_close(partition_fd) < 0) { D(ERR, "could not close device %s", strerror(errno)); fastboot_fail(phandle, "failed to erase partition"); return; } fastboot_okay(phandle, ""); }
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); } }
/** * fastboot_getvar() - Writes variable indicated by cmd_parameter to response. * * @cmd_parameter: Pointer to command parameter * @response: Pointer to fastboot response buffer * * Look up cmd_parameter first as an environment variable of the form * fastboot.<cmd_parameter>, if that exists return use its value to set * response. * * Otherwise lookup the name of variable and execute the appropriate * function to return the requested value. */ void fastboot_getvar(char *cmd_parameter, char *response) { if (!cmd_parameter) { fastboot_fail("missing var", response); } else { #define FASTBOOT_ENV_PREFIX "fastboot." int i; char *var_parameter = cmd_parameter; char envstr[FASTBOOT_RESPONSE_LEN]; const char *s; snprintf(envstr, sizeof(envstr) - 1, FASTBOOT_ENV_PREFIX "%s", cmd_parameter); s = env_get(envstr); if (s) { fastboot_response("OKAY", response, "%s", s); return; } strsep(&var_parameter, ":"); for (i = 0; i < ARRAY_SIZE(getvar_dispatch); ++i) { if (!strcmp(getvar_dispatch[i].variable, cmd_parameter)) { getvar_dispatch[i].dispatch(var_parameter, response); return; } } pr_warn("WARNING: unknown variable: %s\n", cmd_parameter); fastboot_fail("Variable not implemented", response); } }
static void cmd_download(struct protocol_handle *phandle, const char *arg) { unsigned len = strtoul(arg, NULL, 16); int old_fd; if (len > 256 * 1024 * 1024) { fastboot_fail(phandle, "data too large"); return; } fastboot_data(phandle, len); old_fd = protocol_get_download(phandle); if (old_fd >= 0) { off_t len = lseek(old_fd, 0, SEEK_END); D(INFO, "disposing of unused fd %d, size %ld", old_fd, len); close(old_fd); } phandle->download_fd = protocol_handle_download(phandle, len); if (phandle->download_fd < 0) { fastboot_fail(phandle, "download failed"); return; } fastboot_okay(phandle, ""); }
static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info, const char *part_name, void *buffer, unsigned int download_bytes) { lbaint_t blkcnt; lbaint_t blks; /* determine number of blocks to write */ blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1)); blkcnt = blkcnt / info->blksz; if (blkcnt > info->size) { error("too large for partition: '%s'\n", part_name); fastboot_fail("too large for partition"); return; } puts("Flashing Raw Image\n"); blks = dev_desc->block_write(dev_desc->dev, info->start, blkcnt, buffer); if (blks != blkcnt) { error("failed writing to device %d\n", dev_desc->dev); fastboot_fail("failed writing to device"); return; } printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz, part_name); fastboot_okay(""); }
void fb_nand_erase(const char *cmd) { 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_erase_partition_setup(part->name); if (ret) return; ret = _fb_nand_erase(mtd, part); if (ret) { error("failed erasing from device %s", mtd->name); fastboot_fail("failed erasing from device"); return; } fastboot_okay(""); }
static int fb_nand_lookup(const char *partname, struct mtd_info **mtd, struct part_info **part) { struct mtd_device *dev; int ret; u8 pnum; ret = mtdparts_init(); if (ret) { error("Cannot initialize MTD partitions\n"); fastboot_fail("cannot init mtdparts"); return ret; } ret = find_dev_and_part(partname, &dev, &pnum, part); if (ret) { error("cannot find partition: '%s'", partname); fastboot_fail("cannot find partition"); return ret; } if (dev->id->type != MTD_DEV_TYPE_NAND) { error("partition '%s' is not stored on a NAND device", partname); fastboot_fail("not a NAND device"); return -EINVAL; } *mtd = get_nand_dev_by_index(dev->id->num); return 0; }
void cmd_flash_mmc(const char *arg, void *data, unsigned sz) { unsigned long long ptn = 0; unsigned long long size = 0; ptn = mmc_ptn_offset(arg); if(ptn == 0) { fastboot_fail("partition table doesn't exist"); return; } if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { fastboot_fail("image is not a boot image"); return; } } size = mmc_ptn_size(arg); if (ROUND_TO_PAGE(sz,511) > size) { fastboot_fail("size too large"); return; } if (mmc_write(ptn , sz, (unsigned int *)data)) { fastboot_fail("flash write failure"); return; } fastboot_okay(""); return; }
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); }
static void fastboot_command_loop(void) { struct fastboot_cmd *cmd; int r; dprintf(ALWAYS,"fastboot: processing commands\n"); again: while (fastboot_state != STATE_ERROR) { memset(buffer, 0, sizeof(buffer)); r = usb_read(buffer, MAX_RSP_SIZE); if (r < 0) break; //no input command buffer[r] = 0; dprintf(ALWAYS,"[fastboot: command buf]-[%s]-[len=%d]\n", buffer, r); dprintf(ALWAYS,"[fastboot]-[download_base:0x%x]-[download_size:0x%x]\n",(unsigned int)download_base,(unsigned int)download_size); /*Pick up matched command and handle it*/ for (cmd = cmdlist; cmd; cmd = cmd->next) { fastboot_state = STATE_COMMAND; if (memcmp(buffer, cmd->prefix, cmd->prefix_len)) { continue; } dprintf(ALWAYS,"[Cmd process]-[buf:%s]-[lenBuf:%s]\n", buffer, buffer + cmd->prefix_len); #ifdef MTK_SECURITY_SW_SUPPORT if( !sec_usbdl_enabled() || cmd->sec_support ) #endif { cmd->handle((const char*) buffer + cmd->prefix_len, (void*) download_base, download_size); } if (fastboot_state == STATE_COMMAND) { #ifdef MTK_SECURITY_SW_SUPPORT if( sec_usbdl_enabled() && !cmd->sec_support ) { fastboot_fail("not support on security"); } else #endif { fastboot_fail("unknown reason"); } } goto again; } dprintf(ALWAYS,"[unknown command]*[%s]*\n", buffer); fastboot_fail("unknown command"); } fastboot_state = STATE_OFFLINE; dprintf(ALWAYS,"fastboot: oops!\n"); }
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(""); }
void fb_nand_flash_write(const char *partname, unsigned int session_id, void *download_buffer, unsigned int download_bytes, char *response) { struct part_info *part; nand_info_t *nand = NULL; int ret; /* initialize the response buffer */ response_str = response; ret = fb_nand_lookup(partname, response, &nand, &part); if (ret) { error("invalid NAND device"); fastboot_fail(response_str, "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; sparse_storage_t sparse; sparse_priv.nand = nand; sparse_priv.part = part; sparse.block_sz = nand->writesize; sparse.start = part->offset / sparse.block_sz; sparse.size = part->size / sparse.block_sz; sparse.name = part->name; sparse.write = fb_nand_sparse_write; ret = store_sparse_image(&sparse, &sparse_priv, session_id, download_buffer); } else { printf("Flashing raw image at offset 0x%llx\n", part->offset); ret = _fb_nand_write(nand, part, download_buffer, part->offset, download_bytes, NULL); printf("........ wrote %u bytes to '%s'\n", download_bytes, part->name); } if (ret) { fastboot_fail(response_str, "error writing the image"); return; } fastboot_okay(response_str, ""); }
int flash_bootloader(void *data, unsigned sz) { struct bootloader_hdr *bootl_hdr = data; struct component_hdr *c_hdr = NULL; int ret = -1; if (sz < sizeof(*bootl_hdr)) { fastboot_fail("dowloaded file size is incorrect !"); return ret; } if (strncmp((char *) bootl_hdr->magic, BOOTLOADER_MAGIC, sizeof(BOOTLOADER_MAGIC) - 1)) { fastboot_fail("invalid bootloader header !"); return ret; } unsigned i; printf("Found bootloader rev %d version %02d.%02d\n", bootl_hdr->revision, bootl_hdr->version.major, bootl_hdr->version.minor); const char *magics[] = { DROIDBOOT_MAGIC, IFWI_MAGIC, SPLASHSCREEN_MAGIC, CAPSULE_MAGIC, ESP_MAGIC}; const char *names[] = { FASTBOOT_OS_NAME, IFWI_NAME, SPLASHSCREEN_NAME, CAPSULE_NAME, ESP_UPDATE_NAME}; bool something_flashed = false; for (i = 0; i < ARRAY_SIZE(magics); i++) { bool present = false; bool flashed = false; c_hdr = NULL; while (next_component_filter(bootl_hdr, &c_hdr, sz, magics[i])) { present = true; printf("flashing %s\n", names[i]); ret = aboot_flash(names[i], c_hdr + 1, c_hdr->size); if (ret != 0 && ret != -EPERM) return ret; if (ret == 0) flashed = true; } if (present && !flashed) { if (!strcmp(names[i], FASTBOOT_OS_NAME)) { error("Bootloader version not supported\n"); return ret; } else print("No valid %s image found\n", names[i]); } something_flashed = something_flashed || flashed; } if (!something_flashed) error("Nothing to be flashed\n"); return 0; }
void fb_mmc_erase(const char *cmd) { int ret; struct blk_desc *dev_desc; disk_partition_t info; lbaint_t blks, blks_start, blks_size, grp_size; struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV); if (mmc == NULL) { error("invalid mmc device"); fastboot_fail("invalid mmc device"); return; } dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { error("invalid mmc device"); fastboot_fail("invalid mmc device"); return; } ret = part_get_info_efi_by_name_or_alias(dev_desc, cmd, &info); if (ret) { error("cannot find partition: '%s'", cmd); fastboot_fail("cannot find partition"); return; } /* Align blocks to erase group size to avoid erasing other partitions */ grp_size = mmc->erase_grp_size; blks_start = (info.start + grp_size - 1) & ~(grp_size - 1); if (info.size >= grp_size) blks_size = (info.size - (blks_start - info.start)) & (~(grp_size - 1)); else blks_size = 0; printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n", blks_start, blks_start + blks_size); blks = dev_desc->block_erase(dev_desc, blks_start, blks_size); if (blks != blks_size) { error("failed erasing from device %d", dev_desc->devnum); fastboot_fail("failed erasing from device"); return; } printf("........ erased " LBAFU " bytes from '%s'\n", blks_size * info.blksz, cmd); fastboot_okay(""); }
void print_partion_info(void) { block_dev_desc_t *dev_desc; disk_partition_t info; int pnum = 0; int i; unsigned long long start; unsigned long long size; 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; } pnum = get_partition_num(dev_desc); for (i = 1; i <= pnum; i++) { if (get_partition_info(dev_desc, i, &info)) break; start = (unsigned long long)info.start * info.blksz; size = (unsigned long long)info.size * info.blksz; printf("part %3d::%12s\t start 0x%08llx, size 0x%08llx\n", i, info.name, start, size); } }
static int oem_uniqueid_handler(int argc, char **argv) { int retval = -1; ST_RESULT result; uint8_t uniqueKey[SECURE_TOKEN_UNIQUE_KEY_SIZE_IN_BYTES]; char hexuniqueKey[SECURE_TOKEN_UNIQUE_KEY_SIZE_IN_BYTES * 3 + 2]; DX_CC_HostInit(); result = sep_sectoken_request_token(uniqueKey); pr_info("sep_sectoken_request_token() == 0x%x\n", result); if (ST_FAIL_SEP_DRIVER_OP == result) pr_info("sep_sectoken_request_token() ==" "ST_FAIL_SEP_DRIVER_OP\n"); retval = (result != ST_SUCCESSFUL); if (retval != 0) fastboot_fail("cannot get uniqueid"); else { snhexdump(hexuniqueKey, sizeof(hexuniqueKey) - 1, uniqueKey, SECURE_TOKEN_UNIQUE_KEY_SIZE_IN_BYTES); pr_info("%s\n", hexuniqueKey); hexdump_buffer(uniqueKey, SECURE_TOKEN_UNIQUE_KEY_SIZE_IN_BYTES, fastboot_info, 16); } fastboot_okay(""); DX_CC_HostFinish(); return retval; }
static void cmd_gpt_layout(struct protocol_handle *phandle, const char *arg) { struct GPT_entry_table *oldtable; int location; struct GPT_content content; const char *device; device = fastboot_getvar("blockdev"); if (!strcmp(device, "")) { fastboot_fail(phandle, "blockdev not defined in config file"); return; } //TODO: add same verification as in cmd_flash if (phandle->download_fd < 0) { fastboot_fail(phandle, "no layout file"); return; } location = GPT_header_location(); oldtable = GPT_get_device(device, location); GPT_default_content(&content, oldtable); if (oldtable == NULL) D(WARN, "Could not get old gpt table"); else GPT_release_device(oldtable); if (!GPT_parse_file(phandle->download_fd, &content)) { fastboot_fail(phandle, "Could not parse partition config file"); return; } if (trigger_gpt_layout(&content)) { fastboot_fail(phandle, "Vendor forbids this opperation"); GPT_release_content(&content); return; } if (!GPT_write_content(device, &content)) { fastboot_fail(phandle, "Unable to write gpt file"); GPT_release_content(&content); return; } GPT_release_content(&content); fastboot_okay(phandle, ""); }
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); }
void protocol_handle_command(struct protocol_handle *phandle, char *buffer) { D(INFO,"fastboot: %s\n", buffer); struct fastboot_cmd *cmd; for (cmd = cmdlist; cmd; cmd = cmd->next) { if (memcmp(buffer, cmd->prefix, cmd->prefix_len)) continue; phandle->state = STATE_COMMAND; cmd->execute(phandle, buffer + cmd->prefix_len); if (phandle->state == STATE_COMMAND) fastboot_fail(phandle, "unknown reason"); return; } fastboot_fail(phandle, "unknown command"); }
static void getvar_product(char *var_parameter, char *response) { const char *board = env_get("board"); if (board) fastboot_okay(board, response); else fastboot_fail("Board not set", response); }
static void getvar_platform(char *var_parameter, char *response) { const char *p = env_get("platform"); if (p) fastboot_okay(p, response); else fastboot_fail("platform not set", response); }
static void cmd_oem(struct protocol_handle *phandle, const char *arg) { const char *response = ""; //TODO: Maybe it should get download descriptor also if (trigger_oem_cmd(arg, &response)) fastboot_fail(phandle, response); else fastboot_okay(phandle, response); }
static void getvar_serialno(char *var_parameter, char *response) { const char *tmp = env_get("serial#"); if (tmp) fastboot_okay(tmp, response); else fastboot_fail("Value not set", response); }
void cmd_erase_mmc(const char *arg, void *data, unsigned sz) { unsigned long long ptn = 0; unsigned int out[512] = {0}; ptn = mmc_ptn_offset(arg); if(ptn == 0) { fastboot_fail("partition table doesn't exist"); return; } /* Simple inefficient version of erase. Just writing 0 in first block */ if (mmc_write(ptn , 512, (unsigned int *)out)) { fastboot_fail("failed to erase partition"); return; } fastboot_okay(""); }
int fastboot_oem_lock(const char *arg, void *data, unsigned sz) { int ret = B_OK; char msg[128] = {0}; int inFactory = 0; int requireConfirmation = 0; ret = sec_is_in_factory(&inFactory); if (ret) return ret; requireConfirmation = inFactory ? 0 : 1; lock_warranty(); while(1) { if(mtk_detect_key(MT65XX_MENU_SELECT_KEY) || !requireConfirmation) //VOL_UP { fastboot_info("Start lock flow\n"); //Invoke security check after confiming "yes" by user ret = fastboot_oem_lock_chk(); if(ret != B_OK) { sprintf(msg, "\nlock failed - Err:0x%x \n", ret); video_printf("lock failed...return to fastboot in 3s\n"); mdelay(3000); fastboot_boot_menu(); fastboot_fail(msg); } else { video_printf("lock Pass...return to fastboot in 3s\n"); mdelay(3000); fastboot_boot_menu(); fastboot_okay(""); } break; } else if(mtk_detect_key(MT65XX_MENU_OK_KEY))//VOL_DOWN { video_printf("return to fastboot in 3s\n"); mdelay(3000); fastboot_boot_menu(); fastboot_okay(""); break; } else { //If we press other keys, discard it. } } return ret; }
void cmd_boot(const char *arg, void *data, unsigned sz) { unsigned kernel_actual; unsigned ramdisk_actual; static struct boot_img_hdr hdr; char *ptr = ((char*) data); if (sz < sizeof(hdr)) { fastboot_fail("invalid bootimage header"); return; } memcpy(&hdr, data, sizeof(hdr)); /* ensure commandline is terminated */ hdr.cmdline[BOOT_ARGS_SIZE-1] = 0; if(target_is_emmc_boot() && hdr.page_size) { page_size = hdr.page_size; page_mask = page_size - 1; } kernel_actual = ROUND_TO_PAGE(hdr.kernel_size, page_mask); ramdisk_actual = ROUND_TO_PAGE(hdr.ramdisk_size, page_mask); if (page_size + kernel_actual + ramdisk_actual < sz) { fastboot_fail("incomplete bootimage"); return; } memmove((void*) KERNEL_ADDR, ptr + page_size, hdr.kernel_size); memmove((void*) RAMDISK_ADDR, ptr + page_size + kernel_actual, hdr.ramdisk_size); fastboot_okay(""); target_battery_charging_enable(0, 1); udc_stop(); boot_linux((void*) KERNEL_ADDR, (void*) TAGS_ADDR, (const char*) hdr.cmdline, board_machtype(), (void*) RAMDISK_ADDR, hdr.ramdisk_size); }
void cmd_erase(const char *arg, void *data, unsigned sz) { struct ptentry *ptn; struct ptable *ptable; ptable = flash_get_ptable(); if (ptable == NULL) { fastboot_fail("partition table doesn't exist"); return; } ptn = ptable_find(ptable, arg); if (ptn == NULL) { fastboot_fail("unknown partition name"); return; } if (flash_erase(ptn)) { fastboot_fail("failed to erase partition"); return; } fastboot_okay(""); }
static void fastboot_command_loop(void) { struct fastboot_cmd *cmd; int r; dprintf(INFO,"fastboot: processing commands\n"); uint8_t *buffer = (uint8_t *)memalign(CACHE_LINE, ROUNDUP(4096, CACHE_LINE)); if (!buffer) { dprintf(CRITICAL, "Could not allocate memory for fastboot buffer\n."); ASSERT(0); } again: while (fastboot_state != STATE_ERROR) { r = usb_read(buffer, MAX_RSP_SIZE); if (r < 0) break; buffer[r] = 0; dprintf(INFO,"fastboot: %s\n", buffer); for (cmd = cmdlist; cmd; cmd = cmd->next) { if (memcmp(buffer, cmd->prefix, cmd->prefix_len)) continue; fastboot_state = STATE_COMMAND; cmd->handle((const char*) buffer + cmd->prefix_len, (void*) download_base, download_size); if (fastboot_state == STATE_COMMAND) fastboot_fail("unknown reason"); goto again; } fastboot_fail("unknown command"); } fastboot_state = STATE_OFFLINE; dprintf(INFO,"fastboot: oops!\n"); free(buffer); }