void cmd_download(const char *arg, void *data, unsigned sz) { char response[MAX_RSP_SIZE]; unsigned len = hex2unsigned(arg); u32 available_memory=0; int r; init_display_xy(); download_size = 0; available_memory = memory_size()-(u32)download_base; dprintf(DBG_LV, "Enter cmd_download Data Length:%d, available_memory:%d\n", len, available_memory); if (len > download_max) { dprintf(DBG_LV, "Data is larger than all partitions size in target.\n"); fastboot_fail_wrapper("Data is larger than all partitions size in target"); return; } if(is_use_ex_download()) { if(available_memory < MEMORY_SIZE_REQ) { dprintf(DBG_LV, "Insufficient memory for DCACHE\n"); fastboot_fail_wrapper("Insufficient memory for DCACHE"); return; } } else { if (len > available_memory) { dprintf(DBG_LV, "Insufficient memory for whole image\n"); fastboot_fail_wrapper("Insufficient memory for whole image"); return; } } snprintf(response, MAX_RSP_SIZE, "DATA%08x", len); if (usb_write(response, strlen(response)) < 0) { return; } if(is_use_ex_download()) { //use ex download download_ex(len); } else { //use normal download download_standard(len); } return; }
unsigned *target_atag_dfo(unsigned *ptr) { int i, j=0 ; tag_dfo_boot *tag_dfo_p; char tmp[11]; char *buffer; buffer = (unsigned char *)get_env("DFO"); if(buffer != NULL) { *ptr++ = ((sizeof(struct tag_header) + sizeof(tag_dfo_boot)) >> 2); *ptr++ = ATAG_DFO_DATA; tag_dfo_p = (tag_dfo_boot *) ptr; for(i = 0; i < DFO_BOOT_COUNT; i++) { do{ tag_dfo_p->name[i][j] = *buffer; j++; }while(*buffer++ != ',' && j < 31); tag_dfo_p->name[i][j-1] = '\0'; j = 0; do{ tmp[j] = *buffer; j++; }while(*buffer++ != ',' && j < 10); tmp[j] = '\0'; if((strncmp("0x", tmp, 2) == 0) || (strncmp("0X", tmp, 2) == 0)) tag_dfo_p->value[i] = hex2unsigned(&tmp[2]); else tag_dfo_p->value[i] = atoi(tmp); j = 0; } ptr += sizeof(tag_dfo_boot)/sizeof(int); for(i = 0; i < DFO_BOOT_COUNT; i++) printf("[DFO-%d] NAME:%s, Value:%d\n",i , tag_dfo_p->name[i], tag_dfo_p->value[i]); } else
static void cmd_download(const char *arg, void *data, unsigned sz) { STACKBUF_DMA_ALIGN(response, MAX_RSP_SIZE); unsigned len = hex2unsigned(arg); int r; download_size = 0; if (len > download_max) { fastboot_fail("data too large"); return; } snprintf(response, MAX_RSP_SIZE, "DATA%08x", len); if (usb_write(response, strlen(response)) < 0) return; r = usb_read(download_base, len); if ((r < 0) || ((unsigned) r != len)) { fastboot_state = STATE_ERROR; return; } download_size = len; fastboot_okay(""); }
void cmd_download(const char *arg, void *data, unsigned sz) { char response[MAX_RSP_SIZE]; unsigned len = hex2unsigned(arg); u32 available_memory=0; //int r; init_display_xy(); download_size = 0; //available_memory = memory_size()-(u32)download_base; // Real code should be: available_memory = memory_size()-((u32)download_base - MEMBASE); // download_base - MEMBASE is maximum of nearly 64M, that is more smaller than real RAM size like 1G, so use whole memory for approximation. available_memory = memory_size(); dprintf(DBG_LV, "Enter cmd_download Data Length:%d, available_memory:%d\n", len, available_memory); if (len > download_max) { dprintf(DBG_LV, "Data is larger than all partitions size in target.\n"); fastboot_fail_wrapper("Data is larger than all partitions size in target"); return; } if(is_use_ex_download(len)) { if(available_memory < MEMORY_SIZE_REQ) { dprintf(DBG_LV, "Insufficient memory for DCACHE\n"); fastboot_fail_wrapper("Insufficient memory for DCACHE"); return; } } else { if (len > available_memory) { dprintf(DBG_LV, "Insufficient memory for whole image\n"); fastboot_fail_wrapper("Insufficient memory for whole image"); return; } } snprintf(response, MAX_RSP_SIZE, "DATA%08x", len); if (usb_write(response, strlen(response)) < 0) { dprintf(DBG_LV, "cmd_download -- usb write fail\n"); return; } if(is_use_ex_download(len)) { //use ex download download_ex(len); } else { //use normal download download_standard(len); } return; }
static void usb_rx_cmd_complete(struct usb_request *req, unsigned actual, int status) { if(status != 0) return; if(actual > 4095) actual = 4095; cmdbuf[actual] = 0; dprintf("\n> %s\n",cmdbuf); // dprintf("usb_rx_cmd_complete() '%s'\n", cmdbuf); if(memcmp(cmdbuf, "reboot", 6) == 0) { tx_status("OKAY"); rx_cmd(); mdelay(100); board_reboot(); } #if 0 if(memcmp(cmdbuf, "debug:", 6) == 0) { void debug(char *cmd, char *resp); memcpy(cmdbuf, "OKAY", 5); tx_status(cmdbuf); rx_cmd(); mdelay(5000); dprintf("NOW!\n"); debug(cmdbuf + 6, cmdbuf + 4); return; } #endif if(memcmp(cmdbuf, "getvar:", 7) == 0) { char response[64]; strcpy(response,"OKAY"); if(!strcmp(cmdbuf + 7, "version")) { strcpy(response + 4, VERSION); } else if(!strcmp(cmdbuf + 7, "product")) { strcpy(response + 4, PRODUCTNAME); } else if(!strcmp(cmdbuf + 7, "serialno")) { strcpy(response + 4, serialno); } else { board_getvar(cmdbuf + 7, response + 4); } tx_status(response); rx_cmd(); return; } if(memcmp(cmdbuf, "download:", 9) == 0) { char status[16]; rx_addr = kernel_addr; rx_length = hex2unsigned(cmdbuf + 9); if (rx_length > (64*1024*1024)) { tx_status("FAILdata too large"); rx_cmd(); return; } kernel_size = rx_length; dprintf("recv data addr=%x size=%x\n", rx_addr, rx_length); strcpy(status,"DATA"); num_to_hex8(rx_length, status + 4); tx_status(status); rx_data(); return; } if(memcmp(cmdbuf, "erase:", 6) == 0){ struct ptentry *ptn; ptn = flash_find_ptn(cmdbuf + 6); if(ptn == 0) { tx_status("FAILpartition does not exist"); rx_cmd(); return; } dprintf("erasing '%s'\n", ptn->name); cprintf("erasing '%s'", ptn->name); if(flash_erase(ptn)) { tx_status("FAILfailed to erase partition"); rx_cmd(); cprintf(" - FAIL\n"); return; } else { dprintf("partition '%s' erased\n", ptn->name); cprintf(" - OKAY\n"); } tx_status("OKAY"); rx_cmd(); return; } if(memcmp(cmdbuf, "flash:", 6) == 0){ struct ptentry *ptn; int extra = 0; ptn = flash_find_ptn(cmdbuf + 6); if(kernel_size == 0) { tx_status("FAILno image downloaded"); rx_cmd(); return; } if(ptn == 0) { tx_status("FAILpartition does not exist"); rx_cmd(); return; } if(!strcmp(ptn->name,"boot") || !strcmp(ptn->name,"recovery")) { if(memcmp((void*) kernel_addr, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { tx_status("FAILimage is not a boot image"); rx_cmd(); return; } } #if REQUIRE_SIGNATURE { unsigned char digest[DIGEST_SIZE]; compute_digest((void*) kernel_addr, kernel_size, digest); if (is_signature_okay(digest, signature, key_engineering)) { dprintf("verified by engineering key\n"); } else { tx_status("FAILsignature did not verify"); rx_cmd(); return; } } #endif if(!strcmp(ptn->name,"system") || !strcmp(ptn->name,"userdata")) { extra = 64; } else { kernel_size = (kernel_size + 2047) & (~2047); } dprintf("writing %d bytes to '%s'\n", kernel_size, ptn->name); cprintf("writing '%s' (%d bytes)", ptn->name, kernel_size); if(flash_write(ptn, extra, (void*) kernel_addr, kernel_size)) { tx_status("FAILflash write failure"); rx_cmd(); cprintf(" - FAIL\n"); return; } else { dprintf("partition '%s' updated\n", ptn->name); cprintf(" - OKAY\n"); } tx_status("OKAY"); rx_cmd(); return; } if(memcmp(cmdbuf, "boot", 4) == 0) { if(init_boot_linux()) { tx_status("FAILinvalid boot image"); rx_cmd(); return; } dprintf("booting linux...\n"); cprintf("\nbooting linux...\n"); tx_status("OKAY"); mdelay(10); usb_shutdown(); boot_linux(); return; } if(memcmp(cmdbuf, "signature", 9) == 0) { if (kernel_size != SIGNATURE_SIZE) { tx_status("FAILsignature not 256 bytes long"); rx_cmd(); return; } memcpy(signature, (void*)kernel_addr, SIGNATURE_SIZE); tx_status("OKAY"); rx_cmd(); return; } tx_status("FAILinvalid command"); rx_cmd(); }