diff --git a/include/arm9/menu.h b/include/arm9/menu.h index 8be8916..f00f514 100644 --- a/include/arm9/menu.h +++ b/include/arm9/menu.h @@ -15,6 +15,7 @@ MENU_STATE_FIRM_LAUNCH_SETTINGS, MENU_STATE_NAND_BACKUP, MENU_STATE_NAND_RESTORE, + MENU_STATE_NAND_FLASH_FIRM, MENU_STATE_FIRM_LAUNCH, MENU_STATE_BROWSER, MENU_STATE_UPDATE, diff --git a/include/arm9/menu_nand.h b/include/arm9/menu_nand.h index 413a52d..0db7986 100644 --- a/include/arm9/menu_nand.h +++ b/include/arm9/menu_nand.h @@ -2,4 +2,4 @@ bool menuDumpNand(const char *filePath); bool menuRestoreNand(const char *filePath); - +bool menuFlashFirmware(const char *filepath); diff --git a/source/arm9/firmwriter.c b/source/arm9/firmwriter.c index 2e4a0cf..b4e3ae8 100644 --- a/source/arm9/firmwriter.c +++ b/source/arm9/firmwriter.c @@ -16,7 +16,7 @@ static size_t totalToWrite; static size_t totalWritten; static size_t curSector; -static void *blockData; +static void *blockData = NULL; static bool protectSig; static bool failure; @@ -28,9 +28,6 @@ if(blockCount < FIRMWRITER_SECTORS_PER_BLOCK * 2) return false; - if(sector % 0x200) - return false; - totalToWrite = blockCount; totalWritten = 0; // + 1 block because we'll write the firm header afterwards @@ -70,6 +67,8 @@ if(!dev_decnand->read_sector(curSector, numSectors, blockData) || memcmp(sourceBuf, blockData, numSectors * 0x200) != 0) { + dumpMem(sourceBuf-0x100, numSectors * 0x200 + 0x100, "should.bin"); + dumpMem(blockData-0x100, numSectors * 0x200 + 0x100, "isnt.bin"); failure = true; return 0; } @@ -85,16 +84,22 @@ if(failure) return false; - return totalWritten == totalToWrite - FIRMWRITER_SECTORS_PER_BLOCK; + return totalWritten >= totalToWrite - FIRMWRITER_SECTORS_PER_BLOCK; } /* returns number of sectors written, 0 == failure */ size_t firmwriterFinish() { - firm_header header; + static firm_header header; void *firmBuf = (void *) FIRM_LOAD_ADDR; void *compBuf = blockData; size_t sector = curSector - totalWritten - FIRMWRITER_SECTORS_PER_BLOCK; + + if(!firmwriterIsDone()) + { + printf("firmwriter is not done yet.\n"); + return false; + } /* read signature from NAND if we want to keep sighax */ if(protectSig) diff --git a/source/arm9/menu.c b/source/arm9/menu.c index fad8287..1e81b29 100644 --- a/source/arm9/menu.c +++ b/source/arm9/menu.c @@ -31,10 +31,11 @@ }; const menu_state_options menu_nand = { - 2, + 3, { {"Backup NAND", MENU_STATE_NAND_BACKUP}, - {"Restore NAND", MENU_STATE_NAND_RESTORE} + {"Restore NAND", MENU_STATE_NAND_RESTORE}, + {"Flash Firmware", MENU_STATE_NAND_FLASH_FIRM} } }; @@ -161,7 +162,16 @@ menuRestoreNand("sdmc:/nand.bin"); uiClearConsoles(); break; - + + case MENU_STATE_NAND_FLASH_FIRM: + path = browseForFile("sdmc:"); + uiClearConsoles(); + if(!path) + break; + menuFlashFirmware(path); + uiClearConsoles(); + break; + case MENU_STATE_OPTIONS_MENU: menuOptions(); uiClearConsoles(); diff --git a/source/arm9/menu_nand.c b/source/arm9/menu_nand.c index 38476f9..8809dd3 100644 --- a/source/arm9/menu_nand.c +++ b/source/arm9/menu_nand.c @@ -10,6 +10,7 @@ #include "arm9/main.h" #include "arm9/menu.h" #include "arm9/timer.h" +#include "arm9/partitions.h" #include "arm9/firmwriter.h" static u64 getFreeSpace(const char *drive) @@ -271,7 +272,6 @@ bool menuFlashFirmware(const char *filepath) { - u8 *updateBuffer = (u8 *) FIRM_LOAD_ADDR; const char *partName = "firm1"; // TODO let the user decide FILINFO fileStat; size_t fwSize; @@ -297,13 +297,6 @@ uiPrintError("Firmware is invalid or corrupted!\n"); goto fail; } - - // verify fastboot magic - if(memcmp(updateBuffer+0x208, "FASTBOOT 3DS ", 0x10) != 0) - { - uiPrintError("Not an update file!\n"); - goto fail; - } if(!partitionGetIndex(partName, &index)) { @@ -313,7 +306,7 @@ partitionGetSectorOffset(index, §or); - if(!uiDialogYesNo("Update", "Cancel", "Flash firmware to %s?", partName)) + if(!uiDialogYesNo("Proceed", "Cancel", "Flash firmware to %s?", partName)) { goto fail; } diff --git a/source/arm9/menu_update.c b/source/arm9/menu_update.c index 8ea25f8..e4a14cb 100644 --- a/source/arm9/menu_update.c +++ b/source/arm9/menu_update.c @@ -94,9 +94,13 @@ partitionGetSectorOffset(index, §or); // printf("writing to offset 0x%x aka 0x%x\n", sector, sector<<9); - uiPrintTextAt(0, 4, "Updating...\n"); + uiPrintTextAt(0, 9, "Updating...\n"); - firmwriterInit(sector, fwSize / 0x200, true); + if(!firmwriterInit(sector, fwSize / 0x200, true)) + { + uiPrintError("Failed to start update process!"); + goto fail; + } size_t numSectors; @@ -108,7 +112,7 @@ numSectors = firmwriterWriteBlock(); if(!numSectors) { - uiPrintError("Failed writing block!"); + uiPrintError("Writing block failed!"); goto fail; } }