int flash_from_file(const char *filename, int raw) { int i, logic_pos, status = 0x200; unsigned char *block, *block_flash, *bad_block; float pct = 0.f; FILE *f = fopen(filename, "rb"); if (!f) { printf("\nError: Failed to open file: %s\n", filename); return -1; } printf("\nFlashing from %s...\n", filename); printf("0x%x block's to write...\n", sfc.size_blocks); if (!f) return -1; if (raw == -1) /* auto */ { fseek(f, 0, SEEK_END); raw = detect_read_write_modus(ftell(f)); if (raw == -1) return -1; fseek(f, 0, SEEK_SET); } block = (unsigned char*) malloc(sfc.block_sz_phys); block_flash = (unsigned char*) malloc(sfc.block_sz_phys); bad_block = (unsigned char*) malloc(sfc.block_sz_phys); unsigned nand_size = sfc.size_bytes; // Dump only 64mb on big nand if ((nand_size == NAND_SIZE_512MB) | (nand_size == NAND_SIZE_256MB)) { nand_size = NAND_SIZE_64MB; } for (i = 0; i < nand_size; i += sfc.block_sz) { memset(block, 0xFF, sizeof (block)); if (!fread(block, 1, sfc.page_sz_phys * sfc.pages_in_block, f)) { printf("Error reading ...\r\n"); return i; } pct = ((float) i / (float) (nand_size)); App.SetProgressValue(pct); // printf("Writing block: 0x%x of 0x%x (%iMB/%iMB)\r\n", sfcx_address_to_block(i) +1 , sfc.size_blocks , (i + sfc.block_sz) >> 20, nand_size >> 20); //Check for bad block sfcx_writereg(SFCX_STATUS, sfcx_readreg(SFCX_STATUS)); sfcx_writereg(SFCX_ADDRESS, i); sfcx_writereg(SFCX_COMMAND, raw ? PHY_PAGE_TO_BUF : LOG_PAGE_TO_BUF); // Wait Busy while ((status = sfcx_readreg(SFCX_STATUS)) & 1); if ((!raw)) { logic_pos = sfcx_readreg(SFCX_PHYSICAL); if (!(logic_pos & 0x04000000)) /* shouldn't happen, unless the existing image is broken. just assume the block is okay. */ { printf("Error: Uh, oh, don't know. Reading @ block %08x failed. logic_pos: %i\r\n", i, sfcx_address_to_block(logic_pos)); logic_pos = i; } logic_pos &= 0x3fffe00; if (logic_pos != i) { printf("Relocating/moving bad block from position 0x%x to 0x%x\r\n", sfcx_address_to_block(i), sfcx_address_to_block(logic_pos)); } } else if (status & 0x40) //Bad Block Management { printf("Bad block ...\r\n"); #if 0 logic_pos = sfc.last_bad_block_pos * sfc.block_sz; sfc.last_bad_block_pos--; sfcx_set_blocknumber(block, sfcx_address_to_block(i)); sfcx_calcecc((int*) block); if (logic_pos != i) { printf("Relocating/moving bad block from position 0x%x to 0x%x\n", sfcx_address_to_block(i), sfcx_address_to_block(logic_pos)); } #endif } else { logic_pos = i; } #if 0 if (sfc.last_bad_block_pos == sfcx_address_to_block(i)) { //We reach the the last entry bad block in reserved area printf("\nWriting only to last entry bad block in the reserved area."); break; } #endif //Erase block in Nand sfcx_erase_block(logic_pos); //Write block to Nand sfcx_write_block(block, logic_pos); } printf("\nWrite done\n"); fclose(f); free(block); free(block_flash); free(bad_block); if (App.Warning("Flashing is complete, reboot the console?") == TRUE) { xenon_smc_power_reboot(); } return 0; }
/** * Allocate memory for a packet buffer for a given netbuf. * * @param buf the netbuf for which to allocate a packet buffer * @param size the size of the packet buffer to allocate * @return pointer to the allocated memory * NULL if no memory could be allocated */ void writeNand(char* path) { FILE *f; int i, reserved_blocks, nand_sz; unsigned char *buf; unsigned long fileLen; // If bigblock 256/512MB console, override NANDsize with 64MB nand_sz = sfc.size_bytes; if (nand_sz == NAND_SIZE_256MB || nand_sz == NAND_SIZE_256MB) nand_sz = NAND_SIZE_64MB; //Only 64MB dumps supported on Big Block consoles console_clrscr(); //Open file f = fopen(path, "rb"); if(f == NULL) { printf(" ! %s not found on device! Aborting write!\n", path); waitforexit(); } printf("\nFile %s opened successfully!\n", path); //Get file length fseek(f, 0, SEEK_END); fileLen=ftell(f); fseek(f, 0, SEEK_SET); //Check for correct filesize if (fileLen == NAND_SIZE_16MB_RAW || fileLen == NAND_SIZE_64MB_RAW) printf("updflash.bin has a valid filesize."); else { printf(" ! Filesize of %s is unsupported!\n", path); waitforexit(); } //Allocate memory to *buffer buf=(unsigned char *)malloc(fileLen); if (!buf) { printf("Memory error!\n"); fclose(f); waitforexit(); } //Read file contents into buffer printf("Please wait while reading file into buffer ... \n"); fread(buf, 1, fileLen, f); fclose(f); printf("Deleting reserved bad block area !\n"); reserved_blocks = sfc.size_blocks-sfc.size_usable_fs; for (i = reserved_blocks * sfc.block_sz; i < nand_sz; i += sfc.block_sz){ sfcx_erase_block(i); } printf("Please wait while writing to NAND...\n"); //Do what ever with buffer for (i = 0; i < sfc.size_bytes_phys; i += sfc.block_sz_phys) { sfcx_erase_block(sfcx_rawaddress_to_block(i)*sfc.block_sz); sfcx_write_block(&buf[i], sfcx_rawaddress_to_block(i)*sfc.block_sz); } printf("\n"); printf("Freeing memory buffer...\n"); free(buf); printf("Flashing NAND finished. Power cycle the Xbox and boot into your fresh Image !\n"); printf(" ! If you flashed a new SMC you have to replug the PSU !\n"); waitforexit(); }