Made CPU info test and made submenus exit from the B button

This commit is contained in:
Lillian Skinner 2024-11-17 01:05:50 -05:00
parent c4624fe1a1
commit 68b089a037
No known key found for this signature in database
11 changed files with 538 additions and 155 deletions

View File

@ -66,4 +66,4 @@ arm9/$(TARGET).elf:
clean: clean:
$(MAKE) -C arm9 clean $(MAKE) -C arm9 clean
$(MAKE) -C arm7 clean $(MAKE) -C arm7 clean
rm -f $(TARGET).prod.srl $(TARGET).dev.srl $(TARGET).dev.tad $(TARGET).arm7 $(TARGET).arm9 rm -f $(TARGET).prod.srl $(TARGET).dev.srl $(TARGET).dev.tad ntrboot.nds $(TARGET).arm7 $(TARGET).arm9

View File

@ -8,6 +8,8 @@
#include <time.h> #include <time.h>
#include "nand/filesystem.h" #include "nand/filesystem.h"
#include "nand/nandfirm.h" #include "nand/nandfirm.h"
#include "nand/chipinfo.h"
#include "nand/sysfile.h"
#include "video.h" #include "video.h"
#include "nitrofs.h" #include "nitrofs.h"
#include "font.h" #include "font.h"
@ -22,8 +24,9 @@
- Detect debugger vs dev - Detect debugger vs dev
- Recover HWInfo - Recover HWInfo
- Back up/restore screen memory - Back up/restore screen memory
- System transfer (way later on) - NandFirm hash checking <-- very very very important!
- System transfer (way later on)
- Why doesn't unmounting NAND get reflected in the file test? - Why doesn't unmounting NAND get reflected in the file test?
*/ */
@ -52,6 +55,8 @@ PrintConsole bottomScreen;
typedef enum { typedef enum {
STARTMENU_FS_MENU, STARTMENU_FS_MENU,
STARTMENU_NF_MENU, STARTMENU_NF_MENU,
STARTMENU_SYSFILE_MENU,
STARTMENU_CHIP_MENU,
STARTMENU_NULL, STARTMENU_NULL,
STARTMENU_TEST, STARTMENU_TEST,
STARTMENU_TEST2, STARTMENU_TEST2,
@ -69,8 +74,10 @@ static int _mainMenu(int cursor)
setMenuHeader(m, "TwlNandTool"); setMenuHeader(m, "TwlNandTool");
setListHeader(m, "START MENU"); setListHeader(m, "START MENU");
addMenuItem(m, "FileSystem Menu", NULL, 0, "Options such as repairing MBR\n and formatting twl_main/photo."); addMenuItem(m, "FileSystem Menu", NULL, 0, "Options such as repairing MBR\n and formatting TWL_MAIN/PHOTO.");
addMenuItem(m, "NandFirm menu", NULL, 0, "NandFirm (stage2) installers\n and version testing."); addMenuItem(m, "NandFirm Menu", NULL, 0, "NandFirm (stage2) installers\n and verification.");
addMenuItem(m, "Sys File Menu", NULL, 0, "Create/recover system files\n like HWInfo, FontTable, and\n cert.sys");
addMenuItem(m, "Chip Info Menu", NULL, 0, "Info on the NAND and CPU.");
addMenuItem(m, "---------------", NULL, 0, ""); addMenuItem(m, "---------------", NULL, 0, "");
addMenuItem(m, "Debug1", NULL, 0, "Font display."); addMenuItem(m, "Debug1", NULL, 0, "Font display.");
addMenuItem(m, "Debug2", NULL, 0, "MBR corruption test."); addMenuItem(m, "Debug2", NULL, 0, "MBR corruption test.");
@ -194,6 +201,14 @@ int main(int argc, char **argv)
nfMain(); nfMain();
break; break;
case STARTMENU_SYSFILE_MENU:
sysfileMain();
break;
case STARTMENU_CHIP_MENU:
chipMain();
break;
case STARTMENU_NULL: case STARTMENU_NULL:
break; break;

140
arm9/src/nand/chipinfo.c Normal file
View File

@ -0,0 +1,140 @@
#include <nds.h>
#include <fat.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <nds/arm9/nand.h>
#include "f_xy.h"
#include "twltool/dsi.h"
#include "nandio.h"
#include "chipinfo.h"
#include "sector0.h"
#include "crypto.h"
#include "../message.h"
#include "../main.h"
#include "../video.h"
static size_t i;
enum {
CHIPMENU_NAND_INFO,
CHIPMENU_CPU_INFO
};
static int _chipMenu(int cursor)
{
Menu* m = newMenu();
setMenuHeader(m, "TwlNandTool");
setListHeader(m, "Chip Info");
addMenuItem(m, "CID Info", NULL, 0, "Get NAND chip information.");
addMenuItem(m, "ConsoleID Info", NULL, 0, "Get CPU information.");
m->cursor = cursor;
//bottom screen
printMenu(m, 1);
while (!programEnd)
{
swiWaitForVBlank();
scanKeys();
if (moveCursor(m))
printMenu(m, 1);
if (keysDown() & KEY_A)
break;
if (keysDown() & KEY_B)
programEnd = true;
}
int result = m->cursor;
freeMenu(m);
return result;
}
int chipMain(void)
{
int cursor = 0;
while (!programEnd)
{
cursor = _chipMenu(cursor);
if (programEnd == false) {
switch (cursor)
{
case CHIPMENU_NAND_INFO:
nandPrintInfo();
break;
case CHIPMENU_CPU_INFO:
cpuPrintInfo();
break;
}
}
}
programEnd = false;
return 0;
}
bool nandPrintInfo(void) {
success = true;
extern nandData nandInfo;
clearScreen(cSUB);
iprintf("\n>> CID (Card IDentification)");
iprintf("\n Brand : %s", nandInfo.NAND_MID_NAME);
iprintf("\n--------------------------------");
iprintf("\nManufacturer ID : 0x%02X", nandInfo.NAND_MID);
iprintf("\nOEM/Application ID : 0x%02X%02X", nandInfo.NAND_OID[0], nandInfo.NAND_OID[1]);
iprintf("\nProduct name : %s", nandInfo.NAND_PNM);
iprintf("\nProduct revision : %02X", nandInfo.NAND_PRV);
iprintf("\nProduct S/N : %02X%02X%02X%02X", nandInfo.NAND_PSN[0], nandInfo.NAND_PSN[1], nandInfo.NAND_PSN[2], nandInfo.NAND_PSN[3]);
iprintf("\nManufacturing date : %02X(%02d 20%02d)",nandInfo.NAND_MDT, nandInfo.NAND_MDT_MONTH, nandInfo.NAND_MDT_YEAR);
printf("\n\n ");
for (i = 16; i > 0;) {
i--;
if ((i + 1) % 2 == 0) {
printf(" ");
}
printf("%02X", CID[i]);
if (i == 8) {
printf("\n ");
}
}
exitFunction();
return success;
}
bool cpuPrintInfo(void) {
success = true;
extern nandData nandInfo;
clearScreen(cSUB);
iprintf("\n>> ConsoleID (CPU ID) ");
iprintf("\n--------------------------------");
iprintf("\n ");
for (i = 8; i > 0;) {
i--;
if ((i + 1) % 2 == 0) {
printf(" ");
}
printf("%02X", consoleID[i]);
if (i == 8) {
printf("\n ");
}
}
iprintf("\n\nManufacturing date range.\nThis is only an estimate!\n\n ");
iprintf("20%02d/%02d to 20%02d/%02d\n", cpuInfo.CPU_START_YEAR, cpuInfo.CPU_START_MONTH, cpuInfo.CPU_END_YEAR, cpuInfo.CPU_END_MONTH);
exitFunction();
return success;
}

21
arm9/src/nand/chipinfo.h Normal file
View File

@ -0,0 +1,21 @@
#include <nds.h>
#include <fat.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <nds/arm9/nand.h>
#include "f_xy.h"
#include "twltool/dsi.h"
#include "nandio.h"
#include "sector0.h"
#include "crypto.h"
#include "../message.h"
#include "../main.h"
#include "../video.h"
void wait(int ticks);
int chipMain(void);
bool nandPrintInfo(void);
bool cpuPrintInfo(void);

View File

@ -67,8 +67,7 @@ enum {
FSMENU_MOUNT_NITRO, FSMENU_MOUNT_NITRO,
FSMENU_NULL2, FSMENU_NULL2,
FSMENU_FILETEST_MAIN, FSMENU_FILETEST_MAIN,
FSMENU_FILETEST_NITRO, FSMENU_FILETEST_NITRO
FSMENU_BACK
}; };
static int _fsMenu(int cursor) static int _fsMenu(int cursor)
@ -89,7 +88,6 @@ static int _fsMenu(int cursor)
addMenuItem(m, "------------------", NULL, 0, ""); addMenuItem(m, "------------------", NULL, 0, "");
addMenuItem(m, "File test TWL_MAIN", NULL, 0, "Attempt to make/delete dummy\n file on NAND."); addMenuItem(m, "File test TWL_MAIN", NULL, 0, "Attempt to make/delete dummy\n file on NAND.");
addMenuItem(m, "File test NitroFS", NULL, 0, "Attempt to read file in\n NitroFS."); addMenuItem(m, "File test NitroFS", NULL, 0, "Attempt to read file in\n NitroFS.");
addMenuItem(m, "Back", NULL, 0, "Leave the FileSystem menu.");
m->cursor = cursor; m->cursor = cursor;
@ -106,6 +104,9 @@ static int _fsMenu(int cursor)
if (keysDown() & KEY_A) if (keysDown() & KEY_A)
break; break;
if (keysDown() & KEY_B)
programEnd = true;
} }
int result = m->cursor; int result = m->cursor;
@ -123,54 +124,52 @@ int fsMain(void)
{ {
cursor = _fsMenu(cursor); cursor = _fsMenu(cursor);
switch (cursor) if (programEnd == false) {
{ switch (cursor)
{
case FSMENU_READ_MBR: case FSMENU_READ_MBR:
readMbr(); readMbr();
break; break;
case FSMENU_REPAIR_MBR: case FSMENU_REPAIR_MBR:
repairMbr(false); repairMbr(false);
break; break;
case FSMENU_FORMAT_MAIN: case FSMENU_FORMAT_MAIN:
formatMain(); formatMain();
break; break;
case FSMENU_FORMAT_PHOTO: case FSMENU_FORMAT_PHOTO:
formatPhoto(); formatPhoto();
break; break;
case FSMENU_NULL: case FSMENU_NULL:
break; break;
case FSMENU_MOUNT_MAIN: case FSMENU_MOUNT_MAIN:
mountMain(); mountMain();
break; break;
case FSMENU_UNMOUNT_MAIN: case FSMENU_UNMOUNT_MAIN:
unmountMain(); unmountMain();
break; break;
case FSMENU_MOUNT_NITRO: case FSMENU_MOUNT_NITRO:
mountNitroFS(); mountNitroFS();
break; break;
case FSMENU_NULL2: case FSMENU_NULL2:
break; break;
case FSMENU_FILETEST_MAIN: case FSMENU_FILETEST_MAIN:
filetestMain(); filetestMain();
break; break;
case FSMENU_FILETEST_NITRO: case FSMENU_FILETEST_NITRO:
filetestNitro(); filetestNitro();
break; break;
}
case FSMENU_BACK:
programEnd = true;
break;
} }
} }

View File

@ -8,27 +8,19 @@
#include "twltool/dsi.h" #include "twltool/dsi.h"
#include "nandio.h" #include "nandio.h"
#include "nandfirm.h" #include "nandfirm.h"
#include "chipinfo.h"
#include "sector0.h" #include "sector0.h"
#include "crypto.h" #include "crypto.h"
#include "../message.h" #include "../message.h"
#include "../main.h" #include "../main.h"
#include "../video.h" #include "../video.h"
void death(char *message, u8 *buffer){
iprintf("\n%s\n", message);
free(buffer);
while(1)swiWaitForVBlank();
}
static size_t i; static size_t i;
enum { enum {
NFMENU_CHECK_VER, NFMENU_CHECK_VER,
NFMENU_IMPORT, NFMENU_IMPORT,
NFMENU_IMPORT_SDMC, NFMENU_IMPORT_SDMC
NFMENU_READ_CID,
NFMENU_READ_CONSOLEID,
NFMENU_BACK
}; };
static int _nfMenu(int cursor) static int _nfMenu(int cursor)
@ -41,9 +33,6 @@ static int _nfMenu(int cursor)
addMenuItem(m, "Check NandFirm", NULL, 0, "Check the stage2 (bootloader)\n version and type."); addMenuItem(m, "Check NandFirm", NULL, 0, "Check the stage2 (bootloader)\n version and type.");
addMenuItem(m, "Import NandFirm", NULL, 0, "Install the standard stage2\n (bootloader).\n\n This stage2 works normally,\n but it is an updated version:\n - v2265-9336 (prod)\n - v2725-9336 (dev)"); addMenuItem(m, "Import NandFirm", NULL, 0, "Install the standard stage2\n (bootloader).\n\n This stage2 works normally,\n but it is an updated version:\n - v2265-9336 (prod)\n - v2725-9336 (dev)");
addMenuItem(m, "Import NandFirm (SDMC)", NULL, 0, "Install the SDMC Launcher\n stage2 (bootloader).\n\n SDMC will remove access to\n the firmware and SHOULD NOT\n BE USED unless otherwise\n told to do so."); addMenuItem(m, "Import NandFirm (SDMC)", NULL, 0, "Install the SDMC Launcher\n stage2 (bootloader).\n\n SDMC will remove access to\n the firmware and SHOULD NOT\n BE USED unless otherwise\n told to do so.");
addMenuItem(m, "CID Info", NULL, 0, "Get NAND chip information.");
addMenuItem(m, "ConsoleID Info", NULL, 0, "Get CPU information.");
addMenuItem(m, "Back", NULL, 0, "Leave the NandFirm menu.");
m->cursor = cursor; m->cursor = cursor;
@ -60,6 +49,9 @@ static int _nfMenu(int cursor)
if (keysDown() & KEY_A) if (keysDown() & KEY_A)
break; break;
if (keysDown() & KEY_B)
programEnd = true;
} }
int result = m->cursor; int result = m->cursor;
@ -77,32 +69,22 @@ int nfMain(void)
{ {
cursor = _nfMenu(cursor); cursor = _nfMenu(cursor);
switch (cursor) if (programEnd == false) {
{ switch (cursor)
{
case NFMENU_CHECK_VER: case NFMENU_CHECK_VER:
nandFirmRead(); nandFirmRead();
break; break;
case NFMENU_IMPORT: case NFMENU_IMPORT:
nandFirmImport(false); nandFirmImport(false);
break; break;
case NFMENU_IMPORT_SDMC: case NFMENU_IMPORT_SDMC:
nandFirmImport(true); nandFirmImport(true);
break; break;
}
case NFMENU_READ_CID:
nandPrintInfo();
break;
case NFMENU_READ_CONSOLEID:
cpuPrintInfo();
break;
case NFMENU_BACK:
programEnd = true;
break;
} }
} }
@ -168,59 +150,4 @@ bool nandFirmImport(bool sdmc) {
exitFunction(); exitFunction();
return success; return success;
}
bool nandPrintInfo(void) {
success = true;
extern nandData nandInfo;
clearScreen(cSUB);
iprintf("\n>> CID (Card IDentification)");
iprintf("\n Brand : %s", nandInfo.NAND_MID_NAME);
iprintf("\n--------------------------------");
iprintf("\nManufacturer ID : 0x%02X", nandInfo.NAND_MID);
iprintf("\nOEM/Application ID : 0x%02X%02X", nandInfo.NAND_OID[0], nandInfo.NAND_OID[1]);
iprintf("\nProduct name : %s", nandInfo.NAND_PNM);
iprintf("\nProduct revision : %02X", nandInfo.NAND_PRV);
iprintf("\nProduct S/N : %02X%02X%02X%02X", nandInfo.NAND_PSN[0], nandInfo.NAND_PSN[1], nandInfo.NAND_PSN[2], nandInfo.NAND_PSN[3]);
if (nandInfo.NAND_MDT_YEAR <= 9) {
iprintf("\nManufacturing date : %02X(%d 200%d)",nandInfo.NAND_MDT, nandInfo.NAND_MDT_MONTH, nandInfo.NAND_MDT_YEAR);
} else {
iprintf("\nManufacturing date : %02X(%d 20%d)",nandInfo.NAND_MDT, nandInfo.NAND_MDT_MONTH, nandInfo.NAND_MDT_YEAR);
}
printf("\n\n ");
for (i = 16; i > 0;) {
i--;
if ((i + 1) % 2 == 0) {
printf(" ");
}
printf("%02X", CID[i]);
if (i == 8) {
printf("\n ");
}
}
exitFunction();
return success;
}
bool cpuPrintInfo(void) {
success = true;
extern nandData nandInfo;
clearScreen(cSUB);
iprintf("\n>> ConsoleID (CPU ID) ");
iprintf("\n--------------------------------");
iprintf("\n\n ");
for (i = 8; i > 0;) {
i--;
if ((i + 1) % 2 == 0) {
printf(" ");
}
printf("%02X", consoleID[i]);
if (i == 8) {
printf("\n ");
}
}
exitFunction();
return success;
} }

View File

@ -14,11 +14,8 @@
#include "../video.h" #include "../video.h"
void wait(int ticks); void wait(int ticks);
void death(char *message, u8 *buffer);
int nfMain(void); int nfMain(void);
bool nandFirmRead(void); bool nandFirmRead(void);
bool nandFirmImport(bool sdmc); bool nandFirmImport(bool sdmc);
bool nandPrintInfo(void);
bool cpuPrintInfo(void);

View File

@ -119,17 +119,105 @@ void nandGetInfo(void) {
} }
void cpuGetInfo(void) { void cpuGetInfo(void) {
switch (consoleID[6]) {
case 0xA1:
switch ((consoleID[5] & 0xF0) >> 4) {
case 6:
cpuInfo.CPU_START_MONTH = 10;
cpuInfo.CPU_START_YEAR = 8;
cpuInfo.CPU_END_MONTH = 1;
cpuInfo.CPU_END_YEAR = 9;
break;
case 7:
cpuInfo.CPU_START_MONTH = 11;
cpuInfo.CPU_START_YEAR = 8;
cpuInfo.CPU_END_MONTH = 1;
cpuInfo.CPU_END_YEAR = 9;
break;
case 8:
cpuInfo.CPU_START_MONTH = 11;
cpuInfo.CPU_START_YEAR = 8;
cpuInfo.CPU_END_MONTH = 1;
cpuInfo.CPU_END_YEAR = 9;
break;
case 9:
cpuInfo.CPU_START_MONTH = 1;
cpuInfo.CPU_START_YEAR = 9;
cpuInfo.CPU_END_MONTH = 2;
cpuInfo.CPU_END_YEAR = 9;
break;
}
break;
case 0xA2:
switch ((consoleID[5] & 0xF0) >> 4) {
case 0:
cpuInfo.CPU_START_MONTH = 2;
cpuInfo.CPU_START_YEAR = 9;
cpuInfo.CPU_END_MONTH = 5;
cpuInfo.CPU_END_YEAR = 9;
break;
case 1:
cpuInfo.CPU_START_MONTH = 2;
cpuInfo.CPU_START_YEAR = 9;
cpuInfo.CPU_END_MONTH = 5;
cpuInfo.CPU_END_YEAR = 9;
break;
case 2:
cpuInfo.CPU_START_MONTH = 7;
cpuInfo.CPU_START_YEAR = 9;
cpuInfo.CPU_END_MONTH = 7;
cpuInfo.CPU_END_YEAR = 9;
break;
case 3:
cpuInfo.CPU_START_MONTH = 7;
cpuInfo.CPU_START_YEAR = 9;
cpuInfo.CPU_END_MONTH = 8;
cpuInfo.CPU_END_YEAR = 9;
break;
case 4:
cpuInfo.CPU_START_MONTH = 9;
cpuInfo.CPU_START_YEAR = 9;
cpuInfo.CPU_END_MONTH = 9;
cpuInfo.CPU_END_YEAR = 9;
break;
}
break;
case 0x20:
switch ((consoleID[5] & 0xF0) >> 4) {
case 1:
cpuInfo.CPU_START_MONTH = 8;
cpuInfo.CPU_START_YEAR = 9;
cpuInfo.CPU_END_MONTH = 6;
cpuInfo.CPU_END_YEAR = 10;
break;
case 2:
cpuInfo.CPU_START_MONTH = 6;
cpuInfo.CPU_START_YEAR = 10;
cpuInfo.CPU_END_MONTH = 1;
cpuInfo.CPU_END_YEAR = 12;
break;
case 3:
cpuInfo.CPU_START_MONTH = 11;
cpuInfo.CPU_START_YEAR = 10;
cpuInfo.CPU_END_MONTH = 3;
cpuInfo.CPU_END_YEAR = 11;
break;
case 4:
cpuInfo.CPU_START_MONTH = 6;
cpuInfo.CPU_START_YEAR = 11;
cpuInfo.CPU_END_MONTH = 7;
cpuInfo.CPU_END_YEAR = 11;
break;
case 5:
cpuInfo.CPU_START_MONTH = 12;
cpuInfo.CPU_START_YEAR = 10;
cpuInfo.CPU_END_MONTH = 5;
cpuInfo.CPU_END_YEAR = 13;
break;
}
break;
}
/* /*
typedef struct {
uint8_t CPU_START_YEAR[2];
uint8_t CPU_START_MONTH[1];
uint8_t CPU_END_YEAR[2];
uint8_t CPU_END_MONTH[2];
} cpuData;
08a* ConsoleIDs (2008/10 to 2009/09): 08a* ConsoleIDs (2008/10 to 2009/09):
08a16 is introduced around 2008/10 and phased out around 2009/01 08a16 is introduced around 2008/10 and phased out around 2009/01
@ -149,9 +237,8 @@ typedef struct {
08201 is introduced around 2009/08 and is phased out around 2010/06 08201 is introduced around 2009/08 and is phased out around 2010/06
08202 is introduced around 2010/06 and is phased out around 2012/01 08202 is introduced around 2010/06 and is phased out around 2012/01
08203 is introduced around 2010/11 and is phased out around 2011/03 08203 is introduced around 2010/11 and is phased out around 2011/03
08205 is introduced around 2010/12 and is phased out around 2013/05
08204 is introduced around 2011/06 and is phased out around 2011/07 08204 is introduced around 2011/06 and is phased out around 2011/07
08205 is introduced around 2010/12 and is phased out around 2013/05
*/ */
} }

View File

@ -37,10 +37,10 @@ typedef struct {
} nandData; } nandData;
typedef struct { typedef struct {
uint8_t CPU_START_YEAR[2]; uint8_t CPU_START_YEAR;
uint8_t CPU_START_MONTH[1]; uint8_t CPU_START_MONTH;
uint8_t CPU_END_YEAR[2]; uint8_t CPU_END_YEAR;
uint8_t CPU_END_MONTH[2]; uint8_t CPU_END_MONTH;
} cpuData; } cpuData;

176
arm9/src/nand/sysfile.c Normal file
View File

@ -0,0 +1,176 @@
#include <nds.h>
#include <fat.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <nds/arm9/nand.h>
#include "f_xy.h"
#include "twltool/dsi.h"
#include "nandio.h"
#include "nandfirm.h"
#include "sysfile.h"
#include "sector0.h"
#include "crypto.h"
#include "../message.h"
#include "../main.h"
#include "../video.h"
static size_t i;
enum {
SYSFILEMENU_RECOVER,
SYSFILEMENU_RECOVER2,
SYSFILEMENU_NULL,
SYSFILEMENU_INIT_N,
SYSFILEMENU_INIT_S,
SYSFILEMENU_INIT_CERT,
SYSFILEMENU_INIT_FONT
};
/*
I just need to plan things out:
- verifyHWInfo
- Just test input HWInfo buffer
- recoverHWInfoShallow
- Check for easy to find file (in mounted TWL_MAIN, then by common HWInfo offsets)
- recoverHWInfoDeep
- Scrap the entire TWL_MAIN byte by byte to find HWInfo (last resort)
- resignHWInfo
Let's design this around edge cases- meet the TWL-CPU-X4 (prototype).
The HWInfo is made up of one "real" HWInfo at the start, then a repeating secondary HWInfo to pad out to 16kb.
40E34ABB 0E81922C 0B2B24E5 CD4864D4 \
637F0199 D385B1AA A893F65E EDADE869 |
DA66D05D 5B31A897 E4AAF339 83FDD161 | "Real" HWInfo signature
128804B7 B7BA3C06 CD5304ED 9642181C |
A57B3B8B 695E1B37 6F7F220B 019C3932 |
8D45C9AE 99550547 71E77ECD 0C442E98 |
E2ECB154 BB4D7305 AF75D324 7231B36A |
A53677B1 EB4D0102 C8F31A43 EED93758 /
01000000 1C000000 01000000 00000000 <-- Region and language info
00414141 50503241 47303538 31000000 <-- Serial number
4A414E48 <-- Launcher TID
785E7A35 9A9B3C08 B9AAE1D5 02D5CD71 <-- No idea what this entire block is!
E7CFDC89 607EC36A 7A680E45 D0B30B50
BBD36599 99731FE3 91F61DDB 8788C2C1
50B19D58 ... and so on for 0x36C bytes.
64E1D65C 2649BBAA EDF4808A 3B5830A0 \
2E0C2E9A 481A0487 E9DC32DB A49BDA8C |
901B5647 2E3473CB 7317122A 2F7ECCE3 | "Real" HWInfo signature
C880187C 0EA2C230 DFFED67A D6AC7C54 |
98676C25 4B1726FF 3EAA6EE4 39A718CA |
EA2ECF98 9B41BA5F 3E32A49F 8262DE7E |
201585B4 E4D27B32 B4D501EE 2B098032 /
01000000 1C000000 01000000 00000000 <-- Region and language info
002E2E02 2E2E022E 2E022E59 02595902 <-- Serial number (completely broken)
4A414E48 <-- Launcher TID
785E7A35 9A9B3C08 B9AAE1D5 02D5CD71 <-- This weird block appears again!
E7CFDC89 607EC36A 7A680E45 D0B30B50
BBD36599 99731FE3 91F61DDB 8788C2C1
50B19D58 ... and so on for 0x36C bytes.
I have no idea what testing this DSi went through. I can't say if this is unique to the X4 or not.
Anyways, the "weird block" is repeated between every HWInfo chunk. We can check for...
- 0x414E48: the common part of the launcher TID
- 0x785E7A35 9A9B3C08 B9AAE1D5 02D5CD71: the "weird block" data after the TID
Then to verify this is a HWInfo, check if the "weird block" is repeated 0x36C + size of HWInfo later.
This will work on retail as well since the "weird block" here is 0xFF padding until 16kb, so it will always repeat.
Never let down the prototype enjoyers, even if this makes the process way more annoying!
Oh also here's another edge case!
The factory HWInfo Secure created by PRE_IMPORT will be entirely 0xFF.
It will only exist in uninitialized units (did not leave the factory).
If you find 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF then do not proceed to recoverHWInfoDeep.
*/
static int _sysfileMenu(int cursor)
{
Menu* m = newMenu();
setMenuHeader(m, "TwlNandTool");
setListHeader(m, "Sys File");
addMenuItem(m, "Find HWINFO_S.dat", NULL, 0, "Search for HWInfo in TWL_MAIN\n then in common offsets.\n\n In most cases this will be\n enough to recover HWInfo.");
addMenuItem(m, "Find HWINFO_S.dat (deep)", NULL, 0, "Do a byte by byte search for\n HWInfo in the NAND.\n\n This is rarely required and\n should be thought of as a last\n resort only.");
addMenuItem(m, "------------------------", NULL, 0, "Leave the NandFirm menu.");
addMenuItem(m, "Init HWINFO_N.dat", NULL, 0, "Create HWINFO_N.dat.\n\n This file is required to boot.");
addMenuItem(m, "Init HWINFO_S.dat", NULL, 0, "Recover and make HWINFO_S.dat.\n\n If HWINFO_S.dat cannot be\n recovered, it cannot be\n recreated and unlaunch will be\n required to boot the launcher.");
addMenuItem(m, "Init cert.sys", NULL, 0, "Create the certificate chain.");
addMenuItem(m, "Init TWLFontTable", NULL, 0, "Create the font data.");
m->cursor = cursor;
//bottom screen
printMenu(m, 1);
while (!programEnd)
{
swiWaitForVBlank();
scanKeys();
if (moveCursor(m))
printMenu(m, 1);
if (keysDown() & KEY_A)
break;
if (keysDown() & KEY_B)
programEnd = true;
}
int result = m->cursor;
freeMenu(m);
return result;
}
int sysfileMain(void)
{
int cursor = 0;
while (!programEnd)
{
cursor = _sysfileMenu(cursor);
if (programEnd == false) {
switch (cursor)
{
case SYSFILEMENU_RECOVER:
break;
case SYSFILEMENU_RECOVER2:
break;
case SYSFILEMENU_NULL:
break;
case SYSFILEMENU_INIT_S:
break;
case SYSFILEMENU_INIT_N:
break;
case SYSFILEMENU_INIT_CERT:
break;
case SYSFILEMENU_INIT_FONT:
break;
}
}
}
programEnd = false;
return 0;
}

21
arm9/src/nand/sysfile.h Normal file
View File

@ -0,0 +1,21 @@
#include <nds.h>
#include <fat.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <nds/arm9/nand.h>
#include "f_xy.h"
#include "twltool/dsi.h"
#include "nandio.h"
#include "sector0.h"
#include "crypto.h"
#include "../message.h"
#include "../main.h"
#include "../video.h"
void wait(int ticks);
int sysfileMain(void);
bool recoverHWInfoShallow(void);
bool recoverHWInfoDeep(void);