mirror of
https://github.com/suchmememanyskill/TegraExplorer.git
synced 2024-11-26 13:52:06 +00:00
(Attempt at) Implement restoring bis
1 switch was harmed in the making of this commit
This commit is contained in:
parent
144dc3a3f5
commit
3f6d1b532c
10 changed files with 287 additions and 13 deletions
2
Makefile
2
Makefile
|
@ -11,7 +11,7 @@ include $(DEVKITARM)/base_rules
|
||||||
IPL_LOAD_ADDR := 0x40003000
|
IPL_LOAD_ADDR := 0x40003000
|
||||||
LPVERSION_MAJOR := 2
|
LPVERSION_MAJOR := 2
|
||||||
LPVERSION_MINOR := 3
|
LPVERSION_MINOR := 3
|
||||||
LPVERSION_BUGFX := 2
|
LPVERSION_BUGFX := 3
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ u8 clipboardhelper = 0;
|
||||||
extern const char sizevalues[4][3];
|
extern const char sizevalues[4][3];
|
||||||
extern int launch_payload(char *path);
|
extern int launch_payload(char *path);
|
||||||
|
|
||||||
menu_item explfilemenu[11] = {
|
menu_item explfilemenu[12] = {
|
||||||
{"-- File Menu --", COLOR_BLUE, -1, 0},
|
{"-- File Menu --", COLOR_BLUE, -1, 0},
|
||||||
{"FILE", COLOR_GREEN, -1, 0},
|
{"FILE", COLOR_GREEN, -1, 0},
|
||||||
{"\nSIZE", COLOR_VIOLET, -1, 0},
|
{"\nSIZE", COLOR_VIOLET, -1, 0},
|
||||||
|
@ -30,7 +30,8 @@ menu_item explfilemenu[11] = {
|
||||||
{"\nDelete file\n", COLOR_RED, DELETE, 1},
|
{"\nDelete file\n", COLOR_RED, DELETE, 1},
|
||||||
{"Launch Payload", COLOR_ORANGE, PAYLOAD, 1},
|
{"Launch Payload", COLOR_ORANGE, PAYLOAD, 1},
|
||||||
{"Launch Script", COLOR_YELLOW, SCRIPT, 1},
|
{"Launch Script", COLOR_YELLOW, SCRIPT, 1},
|
||||||
{"View Hex", COLOR_GREEN, HEXVIEW, 1}
|
{"View Hex", COLOR_GREEN, HEXVIEW, 1},
|
||||||
|
{"Extract Bis", COLOR_RED, DUMPBIS, 1}
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_item explfoldermenu[6] = {
|
menu_item explfoldermenu[6] = {
|
||||||
|
@ -316,7 +317,12 @@ int filemenu(fs_entry file){
|
||||||
else
|
else
|
||||||
explfilemenu[9].property = -1;
|
explfilemenu[9].property = -1;
|
||||||
|
|
||||||
temp = makemenu(explfilemenu, 11);
|
if (strstr(file.name, ".bis") != NULL)
|
||||||
|
explfilemenu[11].property = 1;
|
||||||
|
else
|
||||||
|
explfilemenu[11].property = -1;
|
||||||
|
|
||||||
|
temp = makemenu(explfilemenu, 12);
|
||||||
|
|
||||||
switch (temp){
|
switch (temp){
|
||||||
case COPY:
|
case COPY:
|
||||||
|
@ -337,6 +343,11 @@ int filemenu(fs_entry file){
|
||||||
case HEXVIEW:
|
case HEXVIEW:
|
||||||
viewbytes(getnextloc(currentpath, file.name));
|
viewbytes(getnextloc(currentpath, file.name));
|
||||||
break;
|
break;
|
||||||
|
case DUMPBIS:
|
||||||
|
clearscreen();
|
||||||
|
extract_bis_file(getnextloc(currentpath, file.name), currentpath);
|
||||||
|
btn_wait();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,7 +35,8 @@ enum filemenuoptions {
|
||||||
DELETE,
|
DELETE,
|
||||||
PAYLOAD,
|
PAYLOAD,
|
||||||
SCRIPT,
|
SCRIPT,
|
||||||
HEXVIEW
|
HEXVIEW,
|
||||||
|
DUMPBIS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum foldermenuoptions {
|
enum foldermenuoptions {
|
||||||
|
|
|
@ -38,7 +38,7 @@ void clearscreen(){
|
||||||
|
|
||||||
gfx_box(0, 0, 719, 15, COLOR_WHITE);
|
gfx_box(0, 0, 719, 15, COLOR_WHITE);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
gfx_printf("Tegraexplorer v1.3.2\n");
|
gfx_printf("Tegraexplorer v1.3.3\n");
|
||||||
|
|
||||||
RESETCOLOR;
|
RESETCOLOR;
|
||||||
}
|
}
|
||||||
|
@ -108,11 +108,17 @@ void printbytes(u8 print[], u32 size, u32 offset){
|
||||||
|
|
||||||
int makewaitmenu(char *initialmessage, char *hiddenmessage, int timer){
|
int makewaitmenu(char *initialmessage, char *hiddenmessage, int timer){
|
||||||
clearscreen();
|
clearscreen();
|
||||||
|
return makewaitmenunoclear(initialmessage, hiddenmessage, timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
int makewaitmenunoclear(char *initialmessage, char *hiddenmessage, int timer){
|
||||||
int res;
|
int res;
|
||||||
u32 start = get_tmr_s();
|
u32 start = get_tmr_s();
|
||||||
|
|
||||||
gfx_printf(initialmessage);
|
gfx_printf(initialmessage);
|
||||||
|
|
||||||
|
while (btn_read() != 0);
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
res = btn_read();
|
res = btn_read();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "te.h"
|
#include "te.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
#include "../gfx/gfx.h"
|
||||||
|
|
||||||
#define SWAPCOLOR(color) gfx_printf("%k", color)
|
#define SWAPCOLOR(color) gfx_printf("%k", color)
|
||||||
#define SWAPBGCOLOR(color) gfx_printf("%K", color)
|
#define SWAPBGCOLOR(color) gfx_printf("%K", color)
|
||||||
|
@ -13,3 +14,4 @@ int makefilemenu(fs_entry *files, int amount, char *path);
|
||||||
void printbytes(u8 print[], u32 size, u32 offset);
|
void printbytes(u8 print[], u32 size, u32 offset);
|
||||||
int makewaitmenu(char *initialmessage, char *hiddenmessage, int timer);
|
int makewaitmenu(char *initialmessage, char *hiddenmessage, int timer);
|
||||||
void gfx_print_length(int size, char *toprint);
|
void gfx_print_length(int size, char *toprint);
|
||||||
|
int makewaitmenunoclear(char *initialmessage, char *hiddenmessage, int timer);
|
|
@ -13,6 +13,7 @@
|
||||||
#include "../storage/sdmmc.h"
|
#include "../storage/sdmmc.h"
|
||||||
#include "../storage/nx_emmc.h"
|
#include "../storage/nx_emmc.h"
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
#include "../storage/emummc.h"
|
||||||
|
|
||||||
extern sdmmc_storage_t storage;
|
extern sdmmc_storage_t storage;
|
||||||
extern emmc_part_t *system_part;
|
extern emmc_part_t *system_part;
|
||||||
|
@ -261,7 +262,7 @@ int copy_recursive(char *path, char *dstpath){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dump_emmc_part(char *path, sdmmc_storage_t *storage, emmc_part_t *part){
|
int dump_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
|
||||||
FIL fp;
|
FIL fp;
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
u32 lba_curr = part->lba_start;
|
u32 lba_curr = part->lba_start;
|
||||||
|
@ -272,6 +273,7 @@ int dump_emmc_part(char *path, sdmmc_storage_t *storage, emmc_part_t *part){
|
||||||
u32 pct = 0;
|
u32 pct = 0;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
gfx_printf("Initializing\r");
|
||||||
buf = calloc(16384, sizeof(u8));
|
buf = calloc(16384, sizeof(u8));
|
||||||
|
|
||||||
if ((res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE))){
|
if ((res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE))){
|
||||||
|
@ -284,7 +286,7 @@ int dump_emmc_part(char *path, sdmmc_storage_t *storage, emmc_part_t *part){
|
||||||
|
|
||||||
while (totalSectors > 0){
|
while (totalSectors > 0){
|
||||||
num = MIN(totalSectors, 32);
|
num = MIN(totalSectors, 32);
|
||||||
if (!sdmmc_storage_read(storage, lba_curr, num, buf)){
|
if (!emummc_storage_read(mmcstorage, lba_curr, num, buf)){
|
||||||
message(COLOR_RED, "eMMC read failed!");
|
message(COLOR_RED, "eMMC read failed!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -355,3 +357,230 @@ int dump_emmc_parts(u16 parts, u8 mmctype){
|
||||||
btn_wait();
|
btn_wait();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int restore_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
|
||||||
|
FIL fp;
|
||||||
|
FILINFO fno;
|
||||||
|
u8 *buf;
|
||||||
|
u32 lba_curr = part->lba_start;
|
||||||
|
u32 bytesWritten = 0;
|
||||||
|
u32 totalSectorsDest = part->lba_end - part->lba_start + 1;
|
||||||
|
u64 totalSizeDest = (u64)((u64)totalSectorsDest << 9);
|
||||||
|
u64 totalSize;
|
||||||
|
u32 num = 0;
|
||||||
|
u32 pct = 0;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
gfx_printf("Initializing\r");
|
||||||
|
|
||||||
|
buf = calloc(16384, sizeof(u8));
|
||||||
|
|
||||||
|
if ((res = f_stat(path, &fno))){
|
||||||
|
message(COLOR_RED, "f_stat() failed! err: %d", res);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalSize = fno.fsize;
|
||||||
|
u64 totalSectors = totalSize / NX_EMMC_BLOCKSIZE;
|
||||||
|
|
||||||
|
if (totalSize > totalSizeDest){
|
||||||
|
message(COLOR_RED, "File too big for destenation!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_printf("Flashing %s\n", part->name);
|
||||||
|
|
||||||
|
if (totalSize < totalSizeDest){
|
||||||
|
SWAPCOLOR(COLOR_ORANGE);
|
||||||
|
u8 btnres = makewaitmenunoclear(
|
||||||
|
"File is too small for destenation.\nDo you want to flash it anyway?\n\nVol +/- to Cancel\n",
|
||||||
|
"Power to Confirm",
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
|
RESETCOLOR;
|
||||||
|
|
||||||
|
if (!btnres){
|
||||||
|
gfx_printf("\nCancelled: %s\n\n", part->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gfx_printf("\nFlashing %s\n", part->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((res = f_open(&fp, path, FA_OPEN_ALWAYS | FA_READ))){
|
||||||
|
message(COLOR_RED, "f_open() failed! err: %d", res);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (totalSectors > 0){
|
||||||
|
num = MIN(totalSectors, 32);
|
||||||
|
|
||||||
|
if ((res = f_read(&fp, buf, num * NX_EMMC_BLOCKSIZE, NULL))){
|
||||||
|
message(COLOR_RED, "f_read() failed! err: %d", res);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!emummc_storage_write(mmcstorage, lba_curr, num, buf)){
|
||||||
|
message(COLOR_RED, "eMMC write failed!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lba_curr += num;
|
||||||
|
totalSectors -= num;
|
||||||
|
bytesWritten += num * NX_EMMC_BLOCKSIZE;
|
||||||
|
|
||||||
|
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
|
||||||
|
gfx_printf("Progress: %d%%\r", pct);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_printf(" \r");
|
||||||
|
f_close(&fp);
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int restore_emmc_file(char *path, const char *target, u8 partition, u8 mmctype){
|
||||||
|
connect_mmc(mmctype);
|
||||||
|
|
||||||
|
if (partition){
|
||||||
|
emmc_part_t bootPart;
|
||||||
|
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
|
||||||
|
memset(&bootPart, 0, sizeof(bootPart));
|
||||||
|
|
||||||
|
bootPart.lba_start = 0;
|
||||||
|
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
|
|
||||||
|
strcpy(bootPart.name, target);
|
||||||
|
|
||||||
|
sdmmc_storage_set_mmc_partition(&storage, partition);
|
||||||
|
restore_emmc_part(path, &storage, &bootPart);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sdmmc_storage_set_mmc_partition(&storage, partition);
|
||||||
|
if (connect_part(target)){
|
||||||
|
message(COLOR_RED, "Find of partition failed!\nPart: %s", target);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
restore_emmc_part(path, &storage, system_part);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int restore_bis_using_file(char *path, u8 mmctype){
|
||||||
|
f_mkdir("sd:/tegraexplorer");
|
||||||
|
f_mkdir("sd:/tegraexplorer/bis");
|
||||||
|
clearscreen();
|
||||||
|
|
||||||
|
if (extract_bis_file(path, "sd:/tegraexplorer/bis")){
|
||||||
|
message(COLOR_ORANGE, "Failed to find file!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!makewaitmenunoclear(
|
||||||
|
"\nAre you sure you want to flash these files\nThis could leave your switch unbootable!\n\nVol +/- to cancel\n",
|
||||||
|
"Power to confirm",
|
||||||
|
5
|
||||||
|
))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_printf("\nRestoring BIS...\n\n");
|
||||||
|
|
||||||
|
restore_emmc_file("sd:/tegraexplorer/bis/BOOT0.bin", "BOOT0", 1, mmctype);
|
||||||
|
restore_emmc_file("sd:/tegraexplorer/bis/BOOT1.bin", "BOOT1", 2, mmctype);
|
||||||
|
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-1-Normal-Main", pkg2names[0], 0, mmctype);
|
||||||
|
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-1-Normal-Main", pkg2names[1], 0, mmctype);
|
||||||
|
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-3-SafeMode-Main", pkg2names[2], 0, mmctype);
|
||||||
|
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-3-SafeMode-Main", pkg2names[3], 0, mmctype);
|
||||||
|
|
||||||
|
gfx_printf("\n\nDone!\nPress any button to return");
|
||||||
|
btn_wait();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 DecodeInt(u8* data) {
|
||||||
|
u32 out = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
out |= (data[i] << ((3 - i) * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_fil_size(FIL* in_src, FIL* out_src, int size_src){
|
||||||
|
u8* buff;
|
||||||
|
buff = calloc(16384, sizeof(u8));
|
||||||
|
|
||||||
|
int size = size_src;
|
||||||
|
int copysize;
|
||||||
|
|
||||||
|
while (size > 0){
|
||||||
|
copysize = MIN(16834, size);
|
||||||
|
f_read(in_src, buff, copysize, NULL);
|
||||||
|
f_write(out_src, buff, copysize, NULL);
|
||||||
|
size -= copysize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_part(int size, FIL* in, char *path){
|
||||||
|
FIL out;
|
||||||
|
|
||||||
|
f_open(&out, path, FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
|
copy_fil_size(in, &out, size);
|
||||||
|
f_close(&out);
|
||||||
|
}
|
||||||
|
|
||||||
|
int extract_bis_file(char *path, char *outfolder){
|
||||||
|
FIL in;
|
||||||
|
int res;
|
||||||
|
u8 version[0x10];
|
||||||
|
u8 args;
|
||||||
|
u8 temp[0x4];
|
||||||
|
u32 filesizes[4];
|
||||||
|
|
||||||
|
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
|
||||||
|
message(COLOR_RED, "Opening file failed! err: %d", res);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_read(&in, version, 0x10, NULL);
|
||||||
|
f_read(&in, &args, 1, NULL);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++){
|
||||||
|
f_read(&in, temp, 4, NULL);
|
||||||
|
filesizes[i] = DecodeInt(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_printf("Version: %s\n\n", version);
|
||||||
|
|
||||||
|
/*
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
gfx_printf("%d ", filesizes[i]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
gfx_printf("\nExtracting BOOT0\n");
|
||||||
|
if (args & BOOT0_ARG)
|
||||||
|
gen_part(filesizes[0], &in, getnextloc(outfolder, "BOOT0.bin"));
|
||||||
|
|
||||||
|
gfx_printf("Extracting BOOT1\n");
|
||||||
|
if (args & BOOT1_ARG)
|
||||||
|
gen_part(filesizes[1], &in, getnextloc(outfolder, "BOOT1.bin"));
|
||||||
|
|
||||||
|
gfx_printf("Extracting BCPKG2_1\n");
|
||||||
|
if (args & BCPKG2_1_ARG)
|
||||||
|
gen_part(filesizes[2], &in, getnextloc(outfolder, "BCPKG2-1-Normal-Main"));
|
||||||
|
|
||||||
|
gfx_printf("Extracting BCPKG2_3\n");
|
||||||
|
if (args & BCPKG2_3_ARG)
|
||||||
|
gen_part(filesizes[3], &in, getnextloc(outfolder, "BCPKG2-3-SafeMode-Main"));
|
||||||
|
|
||||||
|
gfx_printf("\n\nDone!\n");
|
||||||
|
|
||||||
|
f_close(&in);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -9,10 +9,17 @@ void makestring(char *in, char **out);
|
||||||
int del_recursive(char *path);
|
int del_recursive(char *path);
|
||||||
int copy_recursive(char *path, char *dstpath);
|
int copy_recursive(char *path, char *dstpath);
|
||||||
int dump_emmc_parts(u16 parts, u8 mmctype);
|
int dump_emmc_parts(u16 parts, u8 mmctype);
|
||||||
|
int extract_bis_file(char *path, char *outfolder);
|
||||||
|
int restore_bis_using_file(char *path, u8 mmctype);
|
||||||
|
|
||||||
#define PART_BOOT 0x1
|
#define PART_BOOT 0x1
|
||||||
#define PART_PKG2 0x2
|
#define PART_PKG2 0x2
|
||||||
|
|
||||||
|
#define BOOT0_ARG 0x80
|
||||||
|
#define BOOT1_ARG 0x40
|
||||||
|
#define BCPKG2_1_ARG 0x20
|
||||||
|
#define BCPKG2_3_ARG 0x10
|
||||||
|
|
||||||
static const char *pkg2names[] = {
|
static const char *pkg2names[] = {
|
||||||
"BCPKG2-1-Normal-Main",
|
"BCPKG2-1-Normal-Main",
|
||||||
"BCPKG2-2-Normal-Sub",
|
"BCPKG2-2-Normal-Sub",
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
char func[11] = "", args[2][128] = {"", ""};
|
char func[11] = "", args[2][128] = {"", ""};
|
||||||
int res, errcode;
|
int res, errcode;
|
||||||
const int scriptver = 131;
|
const int scriptver = 133;
|
||||||
bool forceExit = false;
|
bool forceExit = false;
|
||||||
u32 currentcolor;
|
u32 currentcolor;
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,15 @@ menu_item shutdownmenu[7] = {
|
||||||
{"Reboot to Atmosphere", COLOR_GREEN, AMS, -1}
|
{"Reboot to Atmosphere", COLOR_GREEN, AMS, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_item toolsmenu[7] = {
|
menu_item toolsmenu[8] = {
|
||||||
{"-- TOOLS --\n", COLOR_VIOLET, -1, 0},
|
{"-- TOOLS --\n", COLOR_VIOLET, -1, 0},
|
||||||
{"Back", COLOR_WHITE, -1, 1},
|
{"Back", COLOR_WHITE, -1, 1},
|
||||||
{"\nDisplay Console Info", COLOR_GREEN, DISPLAY_INFO, 1},
|
{"\nDisplay Console Info", COLOR_GREEN, DISPLAY_INFO, 1},
|
||||||
{"Display GPIO pins", COLOR_VIOLET, DISPLAY_GPIO, 1},
|
{"Display GPIO pins", COLOR_VIOLET, DISPLAY_GPIO, 1},
|
||||||
{"Dump Firmware", COLOR_BLUE, DUMPFIRMWARE, 1},
|
{"Dump Firmware", COLOR_BLUE, DUMPFIRMWARE, 1},
|
||||||
{"Dump User Saves", COLOR_YELLOW, DUMPUSERSAVE, 1},
|
{"Dump User Saves", COLOR_YELLOW, DUMPUSERSAVE, 1},
|
||||||
{"[DEBUG] Dump bis", COLOR_RED, DUMP_BOOT, 1}
|
{"[DEBUG] Dump bis", COLOR_RED, DUMP_BOOT, 1},
|
||||||
|
{"[DEBUG] Restore bis", COLOR_RED, RESTORE_BOOT, 1}
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_item formatmenu[4] = {
|
menu_item formatmenu[4] = {
|
||||||
|
@ -104,7 +105,7 @@ void MainMenu_MountSD(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainMenu_Tools(){
|
void MainMenu_Tools(){
|
||||||
res = makemenu(toolsmenu, 7);
|
res = makemenu(toolsmenu, 8);
|
||||||
|
|
||||||
switch(res){
|
switch(res){
|
||||||
case DISPLAY_INFO:
|
case DISPLAY_INFO:
|
||||||
|
@ -128,6 +129,22 @@ void MainMenu_Tools(){
|
||||||
case DUMP_BOOT:
|
case DUMP_BOOT:
|
||||||
dump_emmc_parts(PART_BOOT | PART_PKG2, SYSMMC);
|
dump_emmc_parts(PART_BOOT | PART_PKG2, SYSMMC);
|
||||||
break;
|
break;
|
||||||
|
case RESTORE_BOOT:
|
||||||
|
SWAPCOLOR(COLOR_ORANGE);
|
||||||
|
if (makewaitmenu(
|
||||||
|
"WARNING!\nThis will mess with your switch boot files\nMake a nand backup beforehand!\n\nThis will pull from path:\nsd:/tegraexplorer/boot.bis\n\nVol +/- to cancel\n",
|
||||||
|
"Power to confirm",
|
||||||
|
5
|
||||||
|
))
|
||||||
|
{
|
||||||
|
if (emu_cfg.enabled){
|
||||||
|
if ((res = makemenu(mmcChoice, 3)) >= 0)
|
||||||
|
restore_bis_using_file("sd:/tegraexplorer/boot.bis", res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
restore_bis_using_file("sd:/tegraexplorer/boot.bis", SYSMMC);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@ enum toolsmenu_return {
|
||||||
DISPLAY_GPIO,
|
DISPLAY_GPIO,
|
||||||
DUMPFIRMWARE,
|
DUMPFIRMWARE,
|
||||||
DUMPUSERSAVE,
|
DUMPUSERSAVE,
|
||||||
DUMP_BOOT
|
DUMP_BOOT,
|
||||||
|
RESTORE_BOOT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum formatmenu_return {
|
enum formatmenu_return {
|
||||||
|
|
Loading…
Reference in a new issue