Add NandFirm import

This commit is contained in:
Lillian Skinner 2024-11-11 05:36:38 -05:00
parent 2787a3d5cf
commit e8e64c4c6d
No known key found for this signature in database
9 changed files with 226 additions and 100 deletions

View File

@ -26,7 +26,7 @@ endif
# Print new version if changed
ifeq (,$(findstring $(GIT_VER), $(shell cat include/version.h)))
$(shell printf "\"$(GIT_VER)\"" > ../../nitrofiles/version_twlnandtool)
$(shell echo -n $(GIT_VER) > ../../nitrofiles/version_twlnandtool)
$(shell printf "#ifndef VERSION_H\n#define VERSION_H\n\n#define VERSION \"$(GIT_VER)\"\n\n#endif // VERSION_H\n" > include/version.h)
endif

View File

@ -79,9 +79,8 @@ PrintConsole topScreen;
PrintConsole bottomScreen;
typedef enum {
MENUSTATE_CHECK_NANDFIRM,
MENUSTATE_FS_MENU,
MENUSTATE_CHECK_NANDINFO,
MENUSTATE_NF_MENU,
MENUSTATE_TEST,
MENUSTATE_EXIT
} MenuState;
@ -101,9 +100,8 @@ static int _mainMenu(int cursor)
setMenuHeader(m, "TwlNandTool");
char modeStr[32];
addMenuItem(m, "Check NandFirm", NULL, 0);
addMenuItem(m, "FileSystem Menu", NULL, 0);
addMenuItem(m, "CID Info", NULL, 0);
addMenuItem(m, "NandFirm menu", NULL, 0);
addMenuItem(m, "Debug1", NULL, 0);
addMenuItem(m, "Exit", NULL, 0);
@ -152,9 +150,9 @@ int main(int argc, char **argv)
consoleSign = fifoGetValue32(FIFO_USER_01);
if (consoleSign == 0x00) {
strcpy(consoleSignName, "RETAIL");
strcpy(consoleSignName, "prod");
} else {
strcpy(consoleSignName, "PANDA");
strcpy(consoleSignName, "dev");
}
videoInit();
@ -183,11 +181,18 @@ int main(int argc, char **argv)
if(!nitroFSInit("TwlNandTool.prod.srl") || !nitroFSGood()) {
if(!nitroFSInit("TwlNandTool.dev.srl") || !nitroFSGood()) {
if(!nitroFSInit("ntrboot.nds") || !nitroFSGood()) {
messageBox("nitroFSInit()...\x1B[31mFailed\n\x1B[40m\nSome features will not work.\n\nTry placing the SRL for your DSion your SD card root like this:\n\nSDMC:/TwlNandTool.prod.srl\nSDMC:/TwlNandTool.dev.srl\nSDMC:/ntrboot.nds\n\n");
while (true)
{
swiWaitForVBlank();
scanKeys();
if (keysDown() & KEY_SELECT )
break;
}
messageBox("nitroFSInit()...\x1B[31mFailed\n\x1B[40m\nSome features will not work.\n\nTry placing the SRL for your DSion your SD card root like this:\n\nSDMC:/TwlNandTool.prod.srl\nSDMC:/TwlNandTool.dev.srl\nSDMC:/ntrboot.nds\n");
}
}
}
//return 0;
}
//setup nand access
@ -204,20 +209,16 @@ int main(int argc, char **argv)
switch (cursor)
{
case MENUSTATE_CHECK_NANDFIRM:
nandFirmRead();
break;
case MENUSTATE_FS_MENU:
fsMain();
break;
case MENUSTATE_CHECK_NANDINFO:
nandPrintInfo();
case MENUSTATE_NF_MENU:
nfMain();
break;
case MENUSTATE_TEST:
testRoutine();
debug1();
break;
case MENUSTATE_EXIT:
@ -240,72 +241,27 @@ int main(int argc, char **argv)
return 0;
}
int testRoutine(void) {
int debug1(void) {
clearScreen(cSUB);
iprintf("\n>> Test Area");
iprintf("\n NAND R/W test ");
iprintf("\n>> Debug1");
iprintf("\n NandFirm write ");
iprintf("\n--------------------------------");
int fail=0;
int byteAddress = 0x4E400;
int inputLength = 0x401;
printf("Opening NandFirm...\n");
int byteOffset = byteAddress % SECTOR_SIZE;
int sectorNum = byteAddress / SECTOR_SIZE;
int byteEndOffset = (byteAddress+inputLength) % SECTOR_SIZE;
int sectorEndNum = (byteAddress+inputLength) / SECTOR_SIZE;
iprintf("\nInput address : %02X", byteAddress);
iprintf("\nInput length : %02X", inputLength);
iprintf("\nInput sector : %02X", sectorNum);
iprintf("\nSector offset : %02X", byteOffset);
iprintf("\nEnd sector : %02X", sectorEndNum);
iprintf("\nSector offset : %02X", byteEndOffset);
iprintf("\n");
int i;
if (sectorNum == sectorEndNum) {
// Handle a single sector write differently since it is unpredictable
//nand_ReadSectors(sectorNum, 1, sector_buf);
//memcpy(sector_buf + inputLength, file_buf, inputLength);
//nand_WriteSectors(1, 1, sector_buf);
iprintf("\n%02X to %02X of %02X", byteOffset, byteEndOffset, sectorNum);
iprintf("\n%02X to %02X of file_buf", 0, inputLength);
} else {
for (i = sectorNum; i < sectorEndNum + 1;) {
// Back up sector
//nand_ReadSectors(i, 1, sector_buf);
if (i == sectorNum) {
// Handle the first sector differently since we'll only be writing a partial amount of data
//memcpy(sector_buf + byteOffset, file_buf, SECTOR_SIZE - byteOffset);
iprintf("\n%02X to %02X of %02X", byteOffset, (SECTOR_SIZE), i);
iprintf("\n0 to %02X of file_buf", (SECTOR_SIZE - byteOffset), i);
} else if (i == sectorEndNum) {
// Handle the last sector differently since we'll only be writing a partial amount of data
//memcpy(sector_buf, file_buf + (((i - sectorNum) * SECTOR_SIZE) - byteOffset), byteEndOffset);
iprintf("\n0 to %02X of %02X (end)", byteEndOffset, i);
iprintf("\n%02X to %02X of file_buf", ((i - sectorNum) * SECTOR_SIZE) - byteOffset, (((i - sectorNum) * SECTOR_SIZE) + byteEndOffset) - byteOffset);
} else {
// Handle the middle sectors the same because they'll always be the full sector
//memcpy(sector_buf, file_buf + (((i - sectorNum) * SECTOR_SIZE) - byteOffset), SECTOR_SIZE);
iprintf("\n0 to %02X of %02X", SECTOR_SIZE, i);
iprintf("\n%02X to %02X of file_buf", ((i - sectorNum) * SECTOR_SIZE) - byteOffset, (((i - sectorNum) * SECTOR_SIZE) - byteOffset) + SECTOR_SIZE);
}
i++;
// I need to do a cmp here
// Write sector
//nand_WriteSectors(i, 1, sector_buf);
}
}
iprintf("\n\n\n Please Push Select To Return ");
// Do some check to make sure it is not outside of NAND range.
FILE *file = fopen("nitro:/import/prod/menu-launcher.nand", "r");
if(file) {
// First 0x200 of NandFirm is reserved for MBR
fseek(file, 0, SEEK_END);
int file_length = ftell(file);
fseek(file, 0x200, SEEK_SET);
printf("Importing...\n");
good_nandio_write_file(0x200, file_length - ftell(file), file, false);
printf("Done!\n");
fclose(file);
}
while (true)
{

View File

@ -17,12 +17,14 @@ extern bool unlaunchPatches;
extern bool charging;
extern u8 batteryLevel;
extern u8 region;
extern u32 consoleSign;
extern char consoleSignName[9];
void installMenu();
void titleMenu();
void backupMenu();
void testMenu();
int testRoutine(void);
int debug1();
extern PrintConsole topScreen;
extern PrintConsole bottomScreen;

View File

@ -15,7 +15,6 @@
#include "../video.h"
u32 done=0;
size_t i;
void death(char *message, u8 *buffer){
iprintf("\n%s\n", message);
@ -23,6 +22,98 @@ void death(char *message, u8 *buffer){
while(1)swiWaitForVBlank();
}
static size_t i;
enum {
MENUSTATE_CHECK_NF_VER,
MENUSTATE_IMPORT_NF,
MENUSTATE_IMPORT_NF_SDMC,
MENUSTATE_READ_CID,
BACK
};
static int _nfMenu(int cursor)
{
//top screen
clearScreen(cMAIN);
printf("\n\x1B[40mTwlNandTool Ver0.0");
printf("\n\nNAND repair tool by RMC/RVTR");
printf("\n\nMode: NandFirm");
//menu
Menu* m = newMenu();
setMenuHeader(m, "TwlNandTool");
char modeStr[32];
addMenuItem(m, "Check NandFirm", NULL, 0);
addMenuItem(m, "Import NandFirm", NULL, 0);
addMenuItem(m, "Import NandFirm (SDMC)", NULL, 0);
addMenuItem(m, "CID Info", NULL, 0);
addMenuItem(m, "Back", NULL, 0);
m->cursor = cursor;
//bottom screen
printMenu(m);
while (!programEnd)
{
swiWaitForVBlank();
scanKeys();
if (moveCursor(m))
printMenu(m);
if (keysDown() & KEY_A)
break;
}
int result = m->cursor;
freeMenu(m);
return result;
}
int nfMain(void)
{
int cursor = 0;
while (!programEnd)
{
cursor = _nfMenu(cursor);
switch (cursor)
{
case MENUSTATE_CHECK_NF_VER:
nandFirmRead();
break;
case MENUSTATE_IMPORT_NF:
nandFirmImport(false);
break;
case MENUSTATE_IMPORT_NF_SDMC:
nandFirmImport(true);
break;
case MENUSTATE_READ_CID:
nandPrintInfo();
break;
case BACK:
programEnd = true;
break;
}
}
programEnd = false;
return 0;
}
int nandFirmRead(void) {
clearScreen(cSUB);
@ -62,6 +153,43 @@ int nandFirmRead(void) {
}
}
int nandFirmImport(bool sdmc) {
clearScreen(cSUB);
iprintf("\n>> Debug1");
iprintf("\n NandFirm write ");
iprintf("\n--------------------------------");
printf("Opening NandFirm...\n");
char file_path[100];
snprintf(file_path, 100, "nitro:/import/%s/%s-launcher.nand", consoleSignName, sdmc ? "sdmc" : "menu");
FILE *file = fopen(file_path, "r");
printf("%s\n", file_path);
if(file) {
// First 0x200 of NandFirm is reserved for MBR
fseek(file, 0, SEEK_END);
int file_length = ftell(file);
fseek(file, 0x200, SEEK_SET);
printf("Importing...\n");
good_nandio_write_file(0x200, file_length - ftell(file), file, false);
printf("Done!\n");
fclose(file);
}
while (true)
{
swiWaitForVBlank();
scanKeys();
if (keysDown() & KEY_SELECT )
break;
}
}
int nandPrintInfo(void) {
extern nandData nandInfo;
@ -96,21 +224,4 @@ int nandPrintInfo(void) {
if (keysDown() & KEY_SELECT )
break;
}
}
/*
I'd actually like to make a good RAW NAND R/W routine.
nandRead(byteAddress, amount, infile)
I want to find the sector (626) and sector offset (80) for the hex address below:
Offset: 320592
Sector size: 512
byteOffset = byteAddress % sectorSize and sector = byteAddress / sectorSize
*/
}

View File

@ -15,5 +15,10 @@
void wait(int ticks);
void death(char *message, u8 *buffer);
int nfMain(void);
int nandFirmRead(void);
int nandFirmImport(bool sdmc);
int nandPrintInfo(void);

View File

@ -283,13 +283,61 @@ bool good_nandio_write(int inputAddress, int inputLength, u8 *buffer, bool crypt
//iprintf("\n0 to %02X of %02X", SECTOR_SIZE, i);
//iprintf("\n%02X to %02X of buffer", ((i - sectorNum) * SECTOR_SIZE) - byteOffset, (((i - sectorNum) * SECTOR_SIZE) - byteOffset) + SECTOR_SIZE);
}
// I need to do a cmp here
// I need to do a cmp here t0 save NAND writes
// Write sector
if (crypt == true) {
dsi_nand_crypt(buffer, buffer, 0, SECTOR_SIZE / AES_BLOCK_SIZE);
}
nand_WriteSectors(i, 1, sector_buf);
i++;
// Do some check to make sure it is not outside of NAND range.
}
}
return true;
}
bool good_nandio_write_file(int inputAddress, int inputLength, FILE *fp, bool crypt) {
int byteOffset = inputAddress % SECTOR_SIZE;
int sectorNum = inputAddress / SECTOR_SIZE;
int byteEndOffset = (inputAddress+inputLength) % SECTOR_SIZE;
int sectorEndNum = (inputAddress+inputLength) / SECTOR_SIZE;
int i;
u8 buffer[SECTOR_SIZE];
if (inputLength <= 0x200) {
// Handle a single sector write differently since it is unpredictable
nand_ReadSectors(sectorNum, 1, sector_buf);
fread(buffer, 1, inputLength, fp);
memcpy(sector_buf, buffer, inputLength);
if (crypt == true) {
dsi_nand_crypt(sector_buf, sector_buf, 0, SECTOR_SIZE / AES_BLOCK_SIZE);
}
nand_WriteSectors(sectorNum, 1, sector_buf);
} else {
for (i = sectorNum; i < sectorEndNum + 1;) {
// Back up sector
nand_ReadSectors(i, 1, sector_buf);
if (i == sectorNum) {
// Handle the first sector differently since we'll only be writing a partial amount of data
fread(buffer, 1, SECTOR_SIZE, fp);
memcpy(sector_buf + byteOffset, buffer, SECTOR_SIZE - byteOffset);
} else if (i == sectorEndNum) {
// Handle the last sector differently since we'll only be writing a partial amount of data
fread(buffer, 1, byteEndOffset, fp);
memcpy(sector_buf, buffer - byteOffset, byteEndOffset);
} else {
// Handle the middle sectors the same because they'll always be the full sector
fread(buffer, 1, SECTOR_SIZE, fp);
memcpy(sector_buf, buffer, SECTOR_SIZE);
}
// I need to do a cmp here t0 save NAND writes
// Write sector
if (crypt == true) {
dsi_nand_crypt(buffer, buffer, 0, SECTOR_SIZE / AES_BLOCK_SIZE);
}
nand_WriteSectors(i, 1, sector_buf);
i++;
// Do some check to make sure it is not outside of NAND range.
}
}
return true;

View File

@ -46,6 +46,7 @@ extern u8 CID[16];
extern u8 consoleIDfixed[8];
extern bool good_nandio_write(int inputAddress, int inputLength, u8 *buffer, bool crypt);
extern bool good_nandio_write_file(int inputAddress, int inputLength, FILE *fp, bool crypt);
extern bool nandio_startup();
extern bool nandio_shutdown();

View File

@ -445,9 +445,12 @@ bool nitroFSGood(void) {
int length = ftell(file);
fseek(file, 0, SEEK_SET);
char *version = (char *)malloc((length + 1) * sizeof(char));
char *version = (char *)malloc((length) * sizeof(char));
version[length] = '\0';
fread(version, 1, length, file);
printf("VER |%s|%s|\n", version, VERSION);
nitroFSGood = (strcmp(version, VERSION) == 0);
fclose(file);
}

View File

@ -1 +1 @@
"-"
-2787a3d