mirror of
https://github.com/rvtr/TwlNandTool.git
synced 2025-10-31 06:01:08 -04:00
Made CPU info test and made submenus exit from the B button
This commit is contained in:
parent
c4624fe1a1
commit
68b089a037
2
Makefile
2
Makefile
@ -66,4 +66,4 @@ arm9/$(TARGET).elf:
|
||||
clean:
|
||||
$(MAKE) -C arm9 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
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
#include <time.h>
|
||||
#include "nand/filesystem.h"
|
||||
#include "nand/nandfirm.h"
|
||||
#include "nand/chipinfo.h"
|
||||
#include "nand/sysfile.h"
|
||||
#include "video.h"
|
||||
#include "nitrofs.h"
|
||||
#include "font.h"
|
||||
@ -22,8 +24,9 @@
|
||||
- Detect debugger vs dev
|
||||
- Recover HWInfo
|
||||
- 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?
|
||||
|
||||
*/
|
||||
@ -52,6 +55,8 @@ PrintConsole bottomScreen;
|
||||
typedef enum {
|
||||
STARTMENU_FS_MENU,
|
||||
STARTMENU_NF_MENU,
|
||||
STARTMENU_SYSFILE_MENU,
|
||||
STARTMENU_CHIP_MENU,
|
||||
STARTMENU_NULL,
|
||||
STARTMENU_TEST,
|
||||
STARTMENU_TEST2,
|
||||
@ -69,8 +74,10 @@ static int _mainMenu(int cursor)
|
||||
setMenuHeader(m, "TwlNandTool");
|
||||
setListHeader(m, "START MENU");
|
||||
|
||||
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, "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 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, "Debug1", NULL, 0, "Font display.");
|
||||
addMenuItem(m, "Debug2", NULL, 0, "MBR corruption test.");
|
||||
@ -194,6 +201,14 @@ int main(int argc, char **argv)
|
||||
nfMain();
|
||||
break;
|
||||
|
||||
case STARTMENU_SYSFILE_MENU:
|
||||
sysfileMain();
|
||||
break;
|
||||
|
||||
case STARTMENU_CHIP_MENU:
|
||||
chipMain();
|
||||
break;
|
||||
|
||||
case STARTMENU_NULL:
|
||||
break;
|
||||
|
||||
|
||||
140
arm9/src/nand/chipinfo.c
Normal file
140
arm9/src/nand/chipinfo.c
Normal 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
21
arm9/src/nand/chipinfo.h
Normal 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);
|
||||
@ -67,8 +67,7 @@ enum {
|
||||
FSMENU_MOUNT_NITRO,
|
||||
FSMENU_NULL2,
|
||||
FSMENU_FILETEST_MAIN,
|
||||
FSMENU_FILETEST_NITRO,
|
||||
FSMENU_BACK
|
||||
FSMENU_FILETEST_NITRO
|
||||
};
|
||||
|
||||
static int _fsMenu(int cursor)
|
||||
@ -89,7 +88,6 @@ static int _fsMenu(int cursor)
|
||||
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 NitroFS", NULL, 0, "Attempt to read file in\n NitroFS.");
|
||||
addMenuItem(m, "Back", NULL, 0, "Leave the FileSystem menu.");
|
||||
|
||||
m->cursor = cursor;
|
||||
|
||||
@ -106,6 +104,9 @@ static int _fsMenu(int cursor)
|
||||
|
||||
if (keysDown() & KEY_A)
|
||||
break;
|
||||
|
||||
if (keysDown() & KEY_B)
|
||||
programEnd = true;
|
||||
}
|
||||
|
||||
int result = m->cursor;
|
||||
@ -123,6 +124,7 @@ int fsMain(void)
|
||||
{
|
||||
cursor = _fsMenu(cursor);
|
||||
|
||||
if (programEnd == false) {
|
||||
switch (cursor)
|
||||
{
|
||||
|
||||
@ -167,10 +169,7 @@ int fsMain(void)
|
||||
case FSMENU_FILETEST_NITRO:
|
||||
filetestNitro();
|
||||
break;
|
||||
|
||||
case FSMENU_BACK:
|
||||
programEnd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,27 +8,19 @@
|
||||
#include "twltool/dsi.h"
|
||||
#include "nandio.h"
|
||||
#include "nandfirm.h"
|
||||
#include "chipinfo.h"
|
||||
#include "sector0.h"
|
||||
#include "crypto.h"
|
||||
#include "../message.h"
|
||||
#include "../main.h"
|
||||
#include "../video.h"
|
||||
|
||||
void death(char *message, u8 *buffer){
|
||||
iprintf("\n%s\n", message);
|
||||
free(buffer);
|
||||
while(1)swiWaitForVBlank();
|
||||
}
|
||||
|
||||
static size_t i;
|
||||
|
||||
enum {
|
||||
NFMENU_CHECK_VER,
|
||||
NFMENU_IMPORT,
|
||||
NFMENU_IMPORT_SDMC,
|
||||
NFMENU_READ_CID,
|
||||
NFMENU_READ_CONSOLEID,
|
||||
NFMENU_BACK
|
||||
NFMENU_IMPORT_SDMC
|
||||
};
|
||||
|
||||
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, "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, "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;
|
||||
|
||||
@ -60,6 +49,9 @@ static int _nfMenu(int cursor)
|
||||
|
||||
if (keysDown() & KEY_A)
|
||||
break;
|
||||
|
||||
if (keysDown() & KEY_B)
|
||||
programEnd = true;
|
||||
}
|
||||
|
||||
int result = m->cursor;
|
||||
@ -77,6 +69,7 @@ int nfMain(void)
|
||||
{
|
||||
cursor = _nfMenu(cursor);
|
||||
|
||||
if (programEnd == false) {
|
||||
switch (cursor)
|
||||
{
|
||||
|
||||
@ -91,18 +84,7 @@ int nfMain(void)
|
||||
case NFMENU_IMPORT_SDMC:
|
||||
nandFirmImport(true);
|
||||
break;
|
||||
|
||||
case NFMENU_READ_CID:
|
||||
nandPrintInfo();
|
||||
break;
|
||||
|
||||
case NFMENU_READ_CONSOLEID:
|
||||
cpuPrintInfo();
|
||||
break;
|
||||
|
||||
case NFMENU_BACK:
|
||||
programEnd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,58 +151,3 @@ bool nandFirmImport(bool sdmc) {
|
||||
exitFunction();
|
||||
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;
|
||||
}
|
||||
@ -14,11 +14,8 @@
|
||||
#include "../video.h"
|
||||
|
||||
void wait(int ticks);
|
||||
void death(char *message, u8 *buffer);
|
||||
|
||||
int nfMain(void);
|
||||
|
||||
bool nandFirmRead(void);
|
||||
bool nandFirmImport(bool sdmc);
|
||||
bool nandPrintInfo(void);
|
||||
bool cpuPrintInfo(void);
|
||||
@ -119,17 +119,105 @@ void nandGetInfo(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):
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
08205 is introduced around 2010/12 and is phased out around 2013/05
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@ -37,10 +37,10 @@ typedef struct {
|
||||
} nandData;
|
||||
|
||||
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];
|
||||
uint8_t CPU_START_YEAR;
|
||||
uint8_t CPU_START_MONTH;
|
||||
uint8_t CPU_END_YEAR;
|
||||
uint8_t CPU_END_MONTH;
|
||||
} cpuData;
|
||||
|
||||
|
||||
|
||||
176
arm9/src/nand/sysfile.c
Normal file
176
arm9/src/nand/sysfile.c
Normal 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
21
arm9/src/nand/sysfile.h
Normal 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);
|
||||
Loading…
Reference in New Issue
Block a user