Merge pull request #13 from suchmememanyskill/dynamic_mmc_mounting
Dynamic mmc mounting
This commit is contained in:
@@ -21,7 +21,9 @@ enum utils_err_codes_te_call {
|
|||||||
ERR_EMMC_WRITE_FAILED,
|
ERR_EMMC_WRITE_FAILED,
|
||||||
ERR_FILE_TOO_BIG_FOR_DEST,
|
ERR_FILE_TOO_BIG_FOR_DEST,
|
||||||
ERR_SD_EJECTED,
|
ERR_SD_EJECTED,
|
||||||
ERR_PARSE_FAIL
|
ERR_PARSE_FAIL,
|
||||||
|
ERR_CANNOT_COPY_FILE_TO_FS_PART,
|
||||||
|
ERR_NO_DESTENATION
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char *utils_err_codes_te[];
|
extern const char *utils_err_codes_te[];
|
||||||
@@ -57,8 +59,7 @@ enum mainmenu_tools_return {
|
|||||||
TOOLS_DISPLAY_INFO = 1,
|
TOOLS_DISPLAY_INFO = 1,
|
||||||
TOOLS_DISPLAY_GPIO,
|
TOOLS_DISPLAY_GPIO,
|
||||||
TOOLS_DUMPFIRMWARE,
|
TOOLS_DUMPFIRMWARE,
|
||||||
TOOLS_DUMPUSERSAVE,
|
TOOLS_DUMPUSERSAVE
|
||||||
TOOLS_DUMP_BOOT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern menu_entry mainmenu_tools[];
|
extern menu_entry mainmenu_tools[];
|
||||||
@@ -104,4 +105,10 @@ enum fs_menu_startdir_return {
|
|||||||
FILEMENU_CURFOLDER
|
FILEMENU_CURFOLDER
|
||||||
};
|
};
|
||||||
|
|
||||||
extern menu_entry fs_menu_startdir[];
|
extern menu_entry fs_menu_startdir[];
|
||||||
|
|
||||||
|
extern gpt_entry_rule gpt_fs_rules[];
|
||||||
|
|
||||||
|
extern menu_entry mmcmenu_start[];
|
||||||
|
|
||||||
|
extern menu_entry mmcmenu_filemenu[];
|
||||||
@@ -50,7 +50,9 @@ const char *utils_err_codes_te[] = { // these start at 50
|
|||||||
"EMMC WRITE FAILED",
|
"EMMC WRITE FAILED",
|
||||||
"FILE TOO BIG FOR DEST",
|
"FILE TOO BIG FOR DEST",
|
||||||
"SD EJECTED",
|
"SD EJECTED",
|
||||||
"PARSING FAILED"
|
"PARSING FAILED",
|
||||||
|
"CANNOT COPY FILE TO FS PART",
|
||||||
|
"NO DESTENATION"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *pkg2names[] = {
|
const char *pkg2names[] = {
|
||||||
|
|||||||
@@ -2,13 +2,9 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
menu_entry mainmenu_main[] = {
|
menu_entry mainmenu_main[] = {
|
||||||
{"[SD:/] SD CARD\n", COLOR_GREEN, ISMENU},
|
{"[SD:/] SD CARD", COLOR_GREEN, ISMENU},
|
||||||
{"[SAFE:/] EMMC", COLOR_ORANGE, ISMENU},
|
{"[EMMC:/] EMMC", COLOR_ORANGE, ISMENU},
|
||||||
{"[SYSTEM:/] EMMC", COLOR_ORANGE, ISMENU},
|
{"[EMMC:/] EMUMMC", COLOR_BLUE, ISMENU},
|
||||||
{"[USER:/] EMMC", COLOR_ORANGE, ISMENU},
|
|
||||||
{"\n[SAFE:/] EMUMMC", COLOR_BLUE, ISMENU},
|
|
||||||
{"[SYSTEM:/] EMUMMC", COLOR_BLUE, ISMENU},
|
|
||||||
{"[USER:/] EMUMMC", COLOR_BLUE, ISMENU},
|
|
||||||
{"\nMount/Unmount SD", COLOR_WHITE, ISMENU},
|
{"\nMount/Unmount SD", COLOR_WHITE, ISMENU},
|
||||||
{"Tools", COLOR_VIOLET, ISMENU},
|
{"Tools", COLOR_VIOLET, ISMENU},
|
||||||
{"SD format", COLOR_VIOLET, ISMENU},
|
{"SD format", COLOR_VIOLET, ISMENU},
|
||||||
@@ -30,8 +26,7 @@ menu_entry mainmenu_tools[] = {
|
|||||||
{"\nDisplay Console Info", COLOR_GREEN, ISMENU},
|
{"\nDisplay Console Info", COLOR_GREEN, ISMENU},
|
||||||
{"Display GPIO pins", COLOR_VIOLET, ISMENU},
|
{"Display GPIO pins", COLOR_VIOLET, ISMENU},
|
||||||
{"Dump Firmware", COLOR_BLUE, ISMENU},
|
{"Dump Firmware", COLOR_BLUE, ISMENU},
|
||||||
{"Dump User Saves", COLOR_YELLOW, ISMENU},
|
{"Dump User Saves", COLOR_YELLOW, ISMENU}
|
||||||
{"Dump bis", COLOR_ORANGE, ISMENU}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_entry mainmenu_format[] = {
|
menu_entry mainmenu_format[] = {
|
||||||
@@ -73,4 +68,26 @@ menu_entry fs_menu_startdir[] = {
|
|||||||
{"Folder -> previous folder ", COLOR_ORANGE, ISMENU},
|
{"Folder -> previous folder ", COLOR_ORANGE, ISMENU},
|
||||||
{"Clipboard -> Current folder ", COLOR_ORANGE, ISMENU},
|
{"Clipboard -> Current folder ", COLOR_ORANGE, ISMENU},
|
||||||
{"Current folder menu ", COLOR_ORANGE, ISMENU}
|
{"Current folder menu ", COLOR_ORANGE, ISMENU}
|
||||||
|
};
|
||||||
|
|
||||||
|
gpt_entry_rule gpt_fs_rules[] = {
|
||||||
|
{"PRODINFOF", 0 | isFS},
|
||||||
|
{"SAFE", 1 | isFS },
|
||||||
|
{"SYSTEM", 2 | isFS},
|
||||||
|
{"USER", 3 | isFS},
|
||||||
|
{NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
menu_entry mmcmenu_start[] = {
|
||||||
|
{"Back", COLOR_ORANGE, ISMENU},
|
||||||
|
{"Dump File Partitions", COLOR_ORANGE, ISMENU},
|
||||||
|
{"Clipboard -> Partition\n", COLOR_ORANGE, ISMENU},
|
||||||
|
{"BOOT0/1", COLOR_BLUE, isBOOT | ISMENU}
|
||||||
|
};
|
||||||
|
|
||||||
|
menu_entry mmcmenu_filemenu[] = {
|
||||||
|
{"Part:", COLOR_ORANGE, ISSKIP | ISMENU},
|
||||||
|
{NULL, COLOR_VIOLET, ISSKIP | ISMENU},
|
||||||
|
{"\nBack", COLOR_WHITE, ISMENU},
|
||||||
|
{"Dump to SD", COLOR_YELLOW, ISMENU}
|
||||||
};
|
};
|
||||||
@@ -43,4 +43,12 @@ typedef struct {
|
|||||||
char *name;
|
char *name;
|
||||||
u32 storage;
|
u32 storage;
|
||||||
u16 property;
|
u16 property;
|
||||||
} menu_entry;
|
} menu_entry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
u8 property;
|
||||||
|
} gpt_entry_rule;
|
||||||
|
|
||||||
|
#define isFS 0x80
|
||||||
|
#define isBOOT 0x2
|
||||||
@@ -22,13 +22,16 @@
|
|||||||
#include "../../config/config.h"
|
#include "../../config/config.h"
|
||||||
#include "../common/common.h"
|
#include "../common/common.h"
|
||||||
#include "../gfx/gfxutils.h"
|
#include "../gfx/gfxutils.h"
|
||||||
|
#include "../../utils/list.h"
|
||||||
|
#include "../../mem/heap.h"
|
||||||
|
|
||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
emmc_part_t *system_part;
|
emmc_part_t *system_part;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
extern hekate_config h_cfg;
|
extern hekate_config h_cfg;
|
||||||
__attribute__ ((aligned (16))) FATFS emmc;
|
__attribute__ ((aligned (16))) FATFS emmc;
|
||||||
LIST_INIT(gpt);
|
LIST_INIT(sys_gpt);
|
||||||
|
LIST_INIT(emu_gpt);
|
||||||
|
|
||||||
u8 bis_key[4][32];
|
u8 bis_key[4][32];
|
||||||
pkg1_info pkg1inf = {-1, ""};
|
pkg1_info pkg1inf = {-1, ""};
|
||||||
@@ -64,7 +67,7 @@ pkg1_info returnpkg1info(){
|
|||||||
int connect_part(const char *partition){
|
int connect_part(const char *partition){
|
||||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||||
|
|
||||||
system_part = nx_emmc_part_find(&gpt, partition);
|
system_part = nx_emmc_part_find(selectGpt(currentlyMounted), partition);
|
||||||
if (!system_part) {
|
if (!system_part) {
|
||||||
gfx_errDisplay("connect_mmc_part", ERR_PART_NOT_FOUND, 0);
|
gfx_errDisplay("connect_mmc_part", ERR_PART_NOT_FOUND, 0);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -213,8 +216,7 @@ int dump_biskeys(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||||
// Parse eMMC GPT.
|
nx_emmc_gpt_parse(&sys_gpt, &storage);
|
||||||
nx_emmc_gpt_parse(&gpt, &storage);
|
|
||||||
|
|
||||||
se_aes_key_set(8, bis_key[2] + 0x00, 0x10);
|
se_aes_key_set(8, bis_key[2] + 0x00, 0x10);
|
||||||
se_aes_key_set(9, bis_key[2] + 0x10, 0x10);
|
se_aes_key_set(9, bis_key[2] + 0x10, 0x10);
|
||||||
@@ -222,4 +224,20 @@ int dump_biskeys(){
|
|||||||
pkg1inf.ver = pkg1_id->kb;
|
pkg1inf.ver = pkg1_id->kb;
|
||||||
strcpy(pkg1inf.id, pkg1_id->id);
|
strcpy(pkg1inf.id, pkg1_id->id);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpEmuGpt(){
|
||||||
|
connect_mmc(EMUMMC);
|
||||||
|
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||||
|
nx_emmc_gpt_parse(&emu_gpt, &storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
link_t *selectGpt(short mmcType){
|
||||||
|
switch(mmcType){
|
||||||
|
case SYSMMC:
|
||||||
|
return &sys_gpt;
|
||||||
|
case EMUMMC:
|
||||||
|
return &emu_gpt;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../../utils/types.h"
|
#include "../../utils/types.h"
|
||||||
|
#include "../../utils/list.h"
|
||||||
|
|
||||||
typedef struct _pkg1_info {
|
typedef struct _pkg1_info {
|
||||||
short ver;
|
short ver;
|
||||||
@@ -15,6 +16,8 @@ int mount_mmc(const char *partition, const int biskeynumb);
|
|||||||
void connect_mmc(short mmctype);
|
void connect_mmc(short mmctype);
|
||||||
void disconnect_mmc();
|
void disconnect_mmc();
|
||||||
int connect_part(const char *partition);
|
int connect_part(const char *partition);
|
||||||
|
void dumpEmuGpt();
|
||||||
|
link_t *selectGpt(short mmcType);
|
||||||
|
|
||||||
static const u8 zeros[0x10] = {0};
|
static const u8 zeros[0x10] = {0};
|
||||||
|
|
||||||
|
|||||||
@@ -68,11 +68,25 @@ int dump_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int existsCheck(char *path){
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
if (fsutil_checkfile(path)){
|
||||||
|
gfx_printf("File already exists! Overwrite?\nVol +/- to cancel\n");
|
||||||
|
res = gfx_makewaitmenu("Power to continue", 3);
|
||||||
|
gfx_printf("\r \r");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
int dump_emmc_parts(u16 parts, u8 mmctype){
|
int dump_emmc_parts(u16 parts, u8 mmctype){
|
||||||
char *path;
|
char *path;
|
||||||
char basepath[] = "sd:/tegraexplorer/dumps";
|
char basepath[] = "sd:/tegraexplorer/partition_dumps";
|
||||||
f_mkdir("sd:/tegraexplorer");
|
f_mkdir("sd:/tegraexplorer");
|
||||||
f_mkdir("sd:/tegraexplorer/dumps");
|
f_mkdir("sd:/tegraexplorer/partition_dumps");
|
||||||
|
|
||||||
connect_mmc(mmctype);
|
connect_mmc(mmctype);
|
||||||
gfx_clearscreen();
|
gfx_clearscreen();
|
||||||
@@ -92,29 +106,79 @@ int dump_emmc_parts(u16 parts, u8 mmctype){
|
|||||||
|
|
||||||
emummc_storage_set_mmc_partition(&storage, i + 1);
|
emummc_storage_set_mmc_partition(&storage, i + 1);
|
||||||
utils_copystring(fsutil_getnextloc(basepath, bootPart.name), &path);
|
utils_copystring(fsutil_getnextloc(basepath, bootPart.name), &path);
|
||||||
|
|
||||||
|
if (!existsCheck(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
gfx_printf("Dumping %s\n", bootPart.name);
|
gfx_printf("Dumping %s\n", bootPart.name);
|
||||||
|
|
||||||
dump_emmc_part(path, &storage, &bootPart);
|
dump_emmc_part(path, &storage, &bootPart);
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
emummc_storage_set_mmc_partition(&storage, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parts & PART_PKG2){
|
if (parts & PART_PKG2){
|
||||||
for (int i = 0; i < 6; i++){
|
for (int i = 0; i < 6; i++){
|
||||||
if (connect_part(pkg2names[i])){
|
utils_copystring(fsutil_getnextloc(basepath, pkg2names[i]), &path);
|
||||||
gfx_errDisplay("dump_emmc_parts", ERR_PART_NOT_FOUND, 0);
|
gfx_printf("Dumping %s\n", pkg2names[i]);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
utils_copystring(fsutil_getnextloc(basepath, system_part->name), &path);
|
emmcDumpSpecific(pkg2names[i], path);
|
||||||
gfx_printf("Dumping %s\n", system_part->name);
|
|
||||||
|
|
||||||
dump_emmc_part(path, &storage, system_part);
|
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx_printf("\nDone!");
|
gfx_printf("\nDone!");
|
||||||
btn_wait();
|
btn_wait();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int emmcDumpBoot(char *basePath){
|
||||||
|
emmc_part_t bootPart;
|
||||||
|
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
|
||||||
|
char *path;
|
||||||
|
memset(&bootPart, 0, sizeof(emmc_part_t));
|
||||||
|
|
||||||
|
bootPart.lba_start = 0;
|
||||||
|
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++){
|
||||||
|
strcpy(bootPart.name, "BOOT");
|
||||||
|
bootPart.name[4] = (u8)('0' + i);
|
||||||
|
bootPart.name[5] = 0;
|
||||||
|
|
||||||
|
emummc_storage_set_mmc_partition(&storage, i + 1);
|
||||||
|
utils_copystring(fsutil_getnextloc(basePath, bootPart.name), &path);
|
||||||
|
|
||||||
|
if (!existsCheck(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SWAPCOLOR(COLOR_BLUE);
|
||||||
|
gfx_printf("Dumping %s\n", bootPart.name);
|
||||||
|
RESETCOLOR;
|
||||||
|
|
||||||
|
dump_emmc_part(path, &storage, &bootPart);
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
emummc_storage_set_mmc_partition(&storage, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int emmcDumpSpecific(char *part, char *path){
|
||||||
|
if (!existsCheck(path))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
emummc_storage_set_mmc_partition(&storage, 0);
|
||||||
|
if (connect_part(part)){
|
||||||
|
gfx_errDisplay("dump_emmc_specific", ERR_PART_NOT_FOUND, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWAPCOLOR(COLOR_VIOLET);
|
||||||
|
gfx_printf("Dumping %s\n", part);
|
||||||
|
RESETCOLOR;
|
||||||
|
dump_emmc_part(path, &storage, system_part);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
242
source/tegraexplorer/emmc/emmcmenu.c
Normal file
242
source/tegraexplorer/emmc/emmcmenu.c
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "emmc.h"
|
||||||
|
#include "../../mem/heap.h"
|
||||||
|
#include "../../utils/types.h"
|
||||||
|
#include "../../libs/fatfs/ff.h"
|
||||||
|
#include "../../utils/sprintf.h"
|
||||||
|
#include "../../utils/btn.h"
|
||||||
|
#include "../../gfx/gfx.h"
|
||||||
|
#include "../../utils/util.h"
|
||||||
|
#include "../../hos/pkg1.h"
|
||||||
|
#include "../../storage/sdmmc.h"
|
||||||
|
#include "../../storage/nx_emmc.h"
|
||||||
|
#include "../../sec/tsec.h"
|
||||||
|
#include "../../soc/t210.h"
|
||||||
|
#include "../../soc/fuse.h"
|
||||||
|
#include "../../mem/mc.h"
|
||||||
|
#include "../../sec/se.h"
|
||||||
|
#include "../../soc/hw_init.h"
|
||||||
|
#include "../../mem/emc.h"
|
||||||
|
#include "../../mem/sdram.h"
|
||||||
|
#include "../../storage/emummc.h"
|
||||||
|
#include "../../config/config.h"
|
||||||
|
#include "../common/common.h"
|
||||||
|
#include "../gfx/gfxutils.h"
|
||||||
|
#include "../../utils/list.h"
|
||||||
|
#include "../../mem/heap.h"
|
||||||
|
#include "emmcmenu.h"
|
||||||
|
#include "../fs/fsreader.h"
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
#include "../gfx/menu.h"
|
||||||
|
#include "../fs/fsmenu.h"
|
||||||
|
#include "emmcoperations.h"
|
||||||
|
#include "../fs/fsutils.h"
|
||||||
|
|
||||||
|
menu_entry *mmcMenuEntries = NULL;
|
||||||
|
extern sdmmc_storage_t storage;
|
||||||
|
extern emmc_part_t *system_part;
|
||||||
|
extern char *clipboard;
|
||||||
|
extern u8 clipboardhelper;
|
||||||
|
|
||||||
|
int checkGptRules(char *in){
|
||||||
|
for (int i = 0; gpt_fs_rules[i].name != NULL; i++){
|
||||||
|
if (!strcmp(in, gpt_fs_rules[i].name))
|
||||||
|
return gpt_fs_rules[i].property;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addEntry(emmc_part_t *part, u8 property, int spot){
|
||||||
|
if (mmcMenuEntries[spot].name != NULL){
|
||||||
|
free(mmcMenuEntries[spot].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
utils_copystring(part->name, &mmcMenuEntries[spot].name);
|
||||||
|
|
||||||
|
if (property & isFS){
|
||||||
|
mmcMenuEntries[spot].storage = (u32)(property & 0x7F);
|
||||||
|
mmcMenuEntries[spot].property = ISDIR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
u64 size = 0;
|
||||||
|
int sizes = 0;
|
||||||
|
mmcMenuEntries[spot].property = 0;
|
||||||
|
size = (part->lba_end + 1 - part->lba_start) * NX_EMMC_BLOCKSIZE;
|
||||||
|
|
||||||
|
while (size > 1024){
|
||||||
|
size /= 1024;
|
||||||
|
sizes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizes > 3)
|
||||||
|
sizes = 0;
|
||||||
|
|
||||||
|
mmcMenuEntries[spot].property |= (1 << (4 + sizes));
|
||||||
|
mmcMenuEntries[spot].storage = (u32)size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int fillMmcMenu(short mmcType){
|
||||||
|
int count = 4, i;
|
||||||
|
|
||||||
|
if (mmcMenuEntries != NULL)
|
||||||
|
clearfileobjects(&mmcMenuEntries);
|
||||||
|
|
||||||
|
link_t *gpt = selectGpt(mmcType);
|
||||||
|
|
||||||
|
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
createfileobjects(count, &mmcMenuEntries);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++){
|
||||||
|
utils_copystring(mmcmenu_start[i].name, &mmcMenuEntries[i].name);
|
||||||
|
mmcMenuEntries[i].property = mmcmenu_start[i].property;
|
||||||
|
mmcMenuEntries[i].storage = mmcmenu_start[i].storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link){
|
||||||
|
addEntry(part, checkGptRules(part->name), i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleEntries(short mmcType, menu_entry part){
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
if (part.property & ISDIR){
|
||||||
|
if (!mount_mmc(part.name, part.storage))
|
||||||
|
fileexplorer("emmc:/", 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (mmcmenu_filemenu[1].name != NULL)
|
||||||
|
free(mmcmenu_filemenu[1].name);
|
||||||
|
|
||||||
|
utils_copystring(part.name, &mmcmenu_filemenu[1].name);
|
||||||
|
|
||||||
|
if ((menu_make(mmcmenu_filemenu, 4, "-- RAW PARTITION --")) < 3)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
f_mkdir("sd:/tegraexplorer");
|
||||||
|
f_mkdir("sd:/tegraexplorer/partition_dumps");
|
||||||
|
|
||||||
|
gfx_clearscreen();
|
||||||
|
|
||||||
|
if (part.property & isBOOT){
|
||||||
|
res = emmcDumpBoot("sd:/tegraexplorer/partition_dumps");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//gfx_printf("Dumping %s...\n", part.name);
|
||||||
|
res = emmcDumpSpecific(part.name, fsutil_getnextloc("sd:/tegraexplorer/partition_dumps", part.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res){
|
||||||
|
gfx_printf("\nDone!");
|
||||||
|
btn_wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
emmc_part_t *mmcFindPart(char *path, short mmcType){
|
||||||
|
char *filename, *extention, *path_local;
|
||||||
|
emmc_part_t *part;
|
||||||
|
|
||||||
|
utils_copystring(path, &path_local);
|
||||||
|
filename = strrchr(path_local, '/') + 1;
|
||||||
|
extention = strrchr(path_local, '.');
|
||||||
|
|
||||||
|
if (extention != NULL)
|
||||||
|
*extention = '\0';
|
||||||
|
|
||||||
|
if (checkGptRules(filename)){
|
||||||
|
gfx_errDisplay("mmcFindPart", ERR_CANNOT_COPY_FILE_TO_FS_PART, 1);
|
||||||
|
free(path_local);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
part = nx_emmc_part_find(selectGpt(mmcType), filename);
|
||||||
|
|
||||||
|
if (part != NULL){
|
||||||
|
emummc_storage_set_mmc_partition(&storage, 0);
|
||||||
|
free(path_local);
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(filename, "BOOT0") || !strcmp(filename, "BOOT1")){
|
||||||
|
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
|
||||||
|
part = calloc(1, sizeof(emmc_part_t));
|
||||||
|
|
||||||
|
part->lba_start = 0;
|
||||||
|
part->lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||||
|
|
||||||
|
strcpy(part->name, filename);
|
||||||
|
|
||||||
|
emummc_storage_set_mmc_partition(&storage, (!strcmp(filename, "BOOT0")) ? 1 : 2);
|
||||||
|
free(path_local);
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
//gfx_printf("Path: %s\nFilename: %s", path, filename);
|
||||||
|
//btn_wait();
|
||||||
|
gfx_errDisplay("mmcFindPart", ERR_NO_DESTENATION, 2);
|
||||||
|
free(path_local);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mmcFlashFile(char *path, short mmcType){
|
||||||
|
emmc_part_t *part;
|
||||||
|
part = mmcFindPart(path, mmcType);
|
||||||
|
if (part != NULL){
|
||||||
|
return restore_emmc_part(path, &storage, part);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int makeMmcMenu(short mmcType){
|
||||||
|
int count, selection;
|
||||||
|
count = fillMmcMenu(mmcType);
|
||||||
|
connect_mmc(mmcType);
|
||||||
|
while (1){
|
||||||
|
selection = menu_make(mmcMenuEntries, count, (mmcType == SYSMMC) ? "-- SYSMMC --" : "-- EMUMMC --");
|
||||||
|
|
||||||
|
switch(selection){
|
||||||
|
case -1:
|
||||||
|
case 0:
|
||||||
|
return 0;
|
||||||
|
case 1:
|
||||||
|
gfx_clearscreen();
|
||||||
|
f_mkdir("sd:/tegraexplorer");
|
||||||
|
f_mkdir("sd:/tegraexplorer/partition_dumps");
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++){
|
||||||
|
if (mmcMenuEntries[i].property & ISMENU || mmcMenuEntries[i].property & ISDIR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//gfx_printf("Dumping %s...\n", mmcMenuEntries[i].name);
|
||||||
|
emmcDumpSpecific(mmcMenuEntries[i].name, fsutil_getnextloc("sd:/tegraexplorer/partition_dumps", mmcMenuEntries[i].name));
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_printf("\nDone!");
|
||||||
|
btn_wait();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (!(clipboardhelper & ISDIR) && (clipboardhelper & OPERATIONCOPY)){
|
||||||
|
gfx_clearscreen();
|
||||||
|
if (!mmcFlashFile(clipboard, mmcType)){
|
||||||
|
gfx_printf("\nDone!");
|
||||||
|
btn_wait();
|
||||||
|
}
|
||||||
|
clipboardhelper = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gfx_errDisplay("mmcMenu", ERR_EMPTY_CLIPBOARD, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
handleEntries(mmcType, mmcMenuEntries[selection]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
source/tegraexplorer/emmc/emmcmenu.h
Normal file
4
source/tegraexplorer/emmc/emmcmenu.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
int makeMmcMenu(short mmcType);
|
||||||
|
int mmcFlashFile(char *path, short mmcType);
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../../utils/types.h"
|
#include "../../utils/types.h"
|
||||||
|
#include "../../storage/nx_emmc.h"
|
||||||
|
|
||||||
int dump_emmc_parts(u16 parts, u8 mmctype);
|
int restore_bis_using_file(char *path, u8 mmctype);
|
||||||
int restore_bis_using_file(char *path, u8 mmctype);
|
int emmcDumpSpecific(char *part, char *path);
|
||||||
|
int restore_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);
|
||||||
|
int emmcDumpBoot(char *basePath);
|
||||||
@@ -105,6 +105,7 @@ int restore_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// function replaced by new mmc implementation. Will be removed at some point
|
||||||
int restore_emmc_file(char *path, const char *target, u8 partition, u8 mmctype){
|
int restore_emmc_file(char *path, const char *target, u8 partition, u8 mmctype){
|
||||||
connect_mmc(mmctype);
|
connect_mmc(mmctype);
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ void copyfile(const char *src_in, const char *outfolder){
|
|||||||
free(out);
|
free(out);
|
||||||
free(filename);
|
free(filename);
|
||||||
fsreader_readfolder(currentpath);
|
fsreader_readfolder(currentpath);
|
||||||
clipboardhelper = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int filemenu(menu_entry file){
|
int filemenu(menu_entry file){
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ void fileexplorer(const char *startpath, int type){
|
|||||||
copyfolder(clipboard, currentpath);
|
copyfolder(clipboard, currentpath);
|
||||||
else
|
else
|
||||||
copyfile(clipboard, currentpath);
|
copyfile(clipboard, currentpath);
|
||||||
|
clipboardhelper = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILEMENU_CURFOLDER:
|
case FILEMENU_CURFOLDER:
|
||||||
|
|||||||
@@ -29,20 +29,20 @@ void fsreader_writeclipboard(const char *in, u8 args){
|
|||||||
utils_copystring(in, &clipboard);
|
utils_copystring(in, &clipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearfileobjects(){
|
void clearfileobjects(menu_entry **menu){
|
||||||
if (fsreader_files != NULL){
|
if ((*menu) != NULL){
|
||||||
for (int i = 0; fsreader_files[i].name != NULL; i++){
|
for (int i = 0; (*menu)[i].name != NULL; i++){
|
||||||
free(fsreader_files[i].name);
|
free((*menu)[i].name);
|
||||||
fsreader_files[i].name = NULL;
|
(*menu)[i].name = NULL;
|
||||||
}
|
}
|
||||||
free(fsreader_files);
|
free((*menu));
|
||||||
fsreader_files = NULL;
|
(*menu) = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void createfileobjects(int size){
|
void createfileobjects(int size, menu_entry **menu){
|
||||||
fsreader_files = calloc (size + 1, sizeof(menu_entry));
|
(*menu) = calloc (size + 1, sizeof(menu_entry));
|
||||||
fsreader_files[size].name = NULL;
|
(*menu)[size].name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addobject(char* name, int spot, u8 attribs){
|
void addobject(char* name, int spot, u8 attribs){
|
||||||
@@ -83,8 +83,8 @@ int fsreader_readfolder(const char *path){
|
|||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
int folderamount, res;
|
int folderamount, res;
|
||||||
|
|
||||||
clearfileobjects();
|
clearfileobjects(&fsreader_files);
|
||||||
createfileobjects(fsutil_getfolderentryamount(path) + 3);
|
createfileobjects(fsutil_getfolderentryamount(path) + 3, &fsreader_files);
|
||||||
|
|
||||||
for (folderamount = 0; folderamount < 3; folderamount++){
|
for (folderamount = 0; folderamount < 3; folderamount++){
|
||||||
utils_copystring(fs_menu_startdir[folderamount].name, &(fsreader_files[folderamount].name));
|
utils_copystring(fs_menu_startdir[folderamount].name, &(fsreader_files[folderamount].name));
|
||||||
|
|||||||
@@ -4,4 +4,7 @@
|
|||||||
extern menu_entry *fsreader_files;
|
extern menu_entry *fsreader_files;
|
||||||
void fsreader_writecurpath(const char *in);
|
void fsreader_writecurpath(const char *in);
|
||||||
void fsreader_writeclipboard(const char *in, u8 args);
|
void fsreader_writeclipboard(const char *in, u8 args);
|
||||||
int fsreader_readfolder(const char *path);
|
int fsreader_readfolder(const char *path);
|
||||||
|
|
||||||
|
void createfileobjects(int size, menu_entry **menu);
|
||||||
|
void clearfileobjects(menu_entry **menu);
|
||||||
@@ -54,7 +54,7 @@ int gfx_errDisplay(char *src_func, int err, int loc){
|
|||||||
|
|
||||||
if (err < 15)
|
if (err < 15)
|
||||||
gfx_printf("Desc: %s\n", utils_err_codes[err]);
|
gfx_printf("Desc: %s\n", utils_err_codes[err]);
|
||||||
else if (err >= ERR_SAME_LOC && err <= ERR_PARSE_FAIL)
|
else if (err >= ERR_SAME_LOC && err <= ERR_NO_DESTENATION)
|
||||||
gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]);
|
gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]);
|
||||||
|
|
||||||
if (loc)
|
if (loc)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "../../utils/util.h"
|
#include "../../utils/util.h"
|
||||||
#include "../../mem/minerva.h"
|
#include "../../mem/minerva.h"
|
||||||
#include "../../soc/gpio.h"
|
#include "../../soc/gpio.h"
|
||||||
#include "gfxutils.h"
|
|
||||||
|
|
||||||
extern void sd_unmount();
|
extern void sd_unmount();
|
||||||
extern bool sd_inited;
|
extern bool sd_inited;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "fs/fsutils.h"
|
#include "fs/fsutils.h"
|
||||||
#include "fs/fsmenu.h"
|
#include "fs/fsmenu.h"
|
||||||
#include "emmc/emmcoperations.h"
|
#include "emmc/emmcoperations.h"
|
||||||
|
#include "emmc/emmcmenu.h"
|
||||||
|
|
||||||
extern bool sd_mount();
|
extern bool sd_mount();
|
||||||
extern void sd_unmount();
|
extern void sd_unmount();
|
||||||
@@ -33,18 +34,24 @@ void MainMenu_EMMC(){
|
|||||||
gfx_clearscreen();
|
gfx_clearscreen();
|
||||||
gfx_printf("You're about to enter EMMC\nModifying anything here\n can result in a BRICK!\n\nPlease only continue\n if you know what you're doing\n\nPress Vol+/- to return\n");
|
gfx_printf("You're about to enter EMMC\nModifying anything here\n can result in a BRICK!\n\nPlease only continue\n if you know what you're doing\n\nPress Vol+/- to return\n");
|
||||||
if (gfx_makewaitmenu("Press Power to enter", 4)){
|
if (gfx_makewaitmenu("Press Power to enter", 4)){
|
||||||
|
/*
|
||||||
connect_mmc(SYSMMC);
|
connect_mmc(SYSMMC);
|
||||||
|
|
||||||
if (!mount_mmc(emmc_fs_entries[res - 2], res - 1))
|
if (!mount_mmc(emmc_fs_entries[res - 2], res - 1))
|
||||||
fileexplorer("emmc:/", 1);
|
fileexplorer("emmc:/", 1);
|
||||||
|
*/
|
||||||
|
makeMmcMenu(SYSMMC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainMenu_EMUMMC(){
|
void MainMenu_EMUMMC(){
|
||||||
|
/*
|
||||||
connect_mmc(EMUMMC);
|
connect_mmc(EMUMMC);
|
||||||
|
|
||||||
if (!mount_mmc(emmc_fs_entries[res - 5], res - 4))
|
if (!mount_mmc(emmc_fs_entries[res - 5], res - 4))
|
||||||
fileexplorer("emmc:/", 1);
|
fileexplorer("emmc:/", 1);
|
||||||
|
*/
|
||||||
|
makeMmcMenu(EMUMMC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainMenu_MountSD(){
|
void MainMenu_MountSD(){
|
||||||
@@ -53,7 +60,7 @@ void MainMenu_MountSD(){
|
|||||||
|
|
||||||
void MainMenu_Tools(){
|
void MainMenu_Tools(){
|
||||||
//res = makemenu(toolsmenu, 8);
|
//res = makemenu(toolsmenu, 8);
|
||||||
res = menu_make(mainmenu_tools, 6, "-- Tools Menu --");
|
res = menu_make(mainmenu_tools, 5, "-- Tools Menu --");
|
||||||
|
|
||||||
switch(res){
|
switch(res){
|
||||||
case TOOLS_DISPLAY_INFO:
|
case TOOLS_DISPLAY_INFO:
|
||||||
@@ -61,6 +68,7 @@ void MainMenu_Tools(){
|
|||||||
break;
|
break;
|
||||||
case TOOLS_DISPLAY_GPIO:
|
case TOOLS_DISPLAY_GPIO:
|
||||||
displaygpio();
|
displaygpio();
|
||||||
|
//makeMmcMenu(SYSMMC);
|
||||||
break;
|
break;
|
||||||
case TOOLS_DUMPFIRMWARE:
|
case TOOLS_DUMPFIRMWARE:
|
||||||
dumpfirmware(SYSMMC);
|
dumpfirmware(SYSMMC);
|
||||||
@@ -70,9 +78,6 @@ void MainMenu_Tools(){
|
|||||||
dumpusersaves(res);
|
dumpusersaves(res);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TOOLS_DUMP_BOOT:
|
|
||||||
dump_emmc_parts(PART_BOOT | PART_PKG2, SYSMMC);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,10 +135,6 @@ void MainMenu_Exit(){
|
|||||||
func_void_ptr mainmenu_functions[] = {
|
func_void_ptr mainmenu_functions[] = {
|
||||||
MainMenu_SDCard,
|
MainMenu_SDCard,
|
||||||
MainMenu_EMMC,
|
MainMenu_EMMC,
|
||||||
MainMenu_EMMC,
|
|
||||||
MainMenu_EMMC,
|
|
||||||
MainMenu_EMUMMC,
|
|
||||||
MainMenu_EMUMMC,
|
|
||||||
MainMenu_EMUMMC,
|
MainMenu_EMUMMC,
|
||||||
MainMenu_MountSD,
|
MainMenu_MountSD,
|
||||||
MainMenu_Tools,
|
MainMenu_Tools,
|
||||||
@@ -143,7 +144,7 @@ func_void_ptr mainmenu_functions[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void RunMenuOption(int option){
|
void RunMenuOption(int option){
|
||||||
if (option != 11)
|
if (option != 7)
|
||||||
meter = 0;
|
meter = 0;
|
||||||
if (option > 0)
|
if (option > 0)
|
||||||
mainmenu_functions[option - 1]();
|
mainmenu_functions[option - 1]();
|
||||||
@@ -153,14 +154,14 @@ void te_main(){
|
|||||||
|
|
||||||
if (dump_biskeys() == -1){
|
if (dump_biskeys() == -1){
|
||||||
gfx_errDisplay("dump_biskey", ERR_BISKEY_DUMP_FAILED, 0);
|
gfx_errDisplay("dump_biskey", ERR_BISKEY_DUMP_FAILED, 0);
|
||||||
for (int i = 1; i <= 3; i++)
|
mainmenu_main[1].property |= ISHIDE;
|
||||||
mainmenu_main[i].property |= ISHIDE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emummc_load_cfg()){
|
if (emummc_load_cfg()){
|
||||||
for (int i = 4; i <= 6; i++)
|
mainmenu_main[2].property |= ISHIDE;
|
||||||
mainmenu_main[i].property |= ISHIDE;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
dumpEmuGpt();
|
||||||
|
|
||||||
disconnect_mmc();
|
disconnect_mmc();
|
||||||
|
|
||||||
@@ -170,17 +171,16 @@ void te_main(){
|
|||||||
setter = sd_mounted;
|
setter = sd_mounted;
|
||||||
|
|
||||||
if (emu_cfg.enabled){
|
if (emu_cfg.enabled){
|
||||||
for (int i = 4; i <= 6; i++)
|
SETBIT(mainmenu_main[2].property, ISHIDE, !setter);
|
||||||
SETBIT(mainmenu_main[i].property, ISHIDE, !setter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SETBIT(mainmenu_main[0].property, ISHIDE, !setter);
|
SETBIT(mainmenu_main[0].property, ISHIDE, !setter);
|
||||||
mainmenu_main[7].name = (menu_sd_states[!setter]);
|
mainmenu_main[3].name = (menu_sd_states[!setter]);
|
||||||
|
|
||||||
setter = sd_inited;
|
setter = sd_inited;
|
||||||
SETBIT(mainmenu_main[9].property, ISHIDE, !setter);
|
SETBIT(mainmenu_main[5].property, ISHIDE, !setter);
|
||||||
|
|
||||||
res = menu_make(mainmenu_main, 12, "-- Main Menu --") + 1;
|
res = menu_make(mainmenu_main, 8, "-- Main Menu --") + 1;
|
||||||
RunMenuOption(res);
|
RunMenuOption(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,11 +19,14 @@
|
|||||||
#include "../fs/fsutils.h"
|
#include "../fs/fsutils.h"
|
||||||
#include "../../utils/sprintf.h"
|
#include "../../utils/sprintf.h"
|
||||||
#include "../fs/fsactions.h"
|
#include "../fs/fsactions.h"
|
||||||
|
#include "../emmc/emmcoperations.h"
|
||||||
|
#include "../emmc/emmcmenu.h"
|
||||||
|
|
||||||
extern FIL scriptin;
|
extern FIL scriptin;
|
||||||
extern char **argv;
|
extern char **argv;
|
||||||
extern u32 argc;
|
extern u32 argc;
|
||||||
extern int forceExit;
|
extern int forceExit;
|
||||||
|
extern short currentlyMounted;
|
||||||
|
|
||||||
int parseIntInput(char *in, int *out){
|
int parseIntInput(char *in, int *out){
|
||||||
if (in[0] == '@'){
|
if (in[0] == '@'){
|
||||||
@@ -462,6 +465,34 @@ int part_fs_combinePath(){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int part_mmc_dumpPart(){
|
||||||
|
char *left, *right;
|
||||||
|
|
||||||
|
if (parseStringInput(argv[0], &left))
|
||||||
|
return -1;
|
||||||
|
if (parseStringInput(argv[1], &right))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!strcmp(left, "BOOT")){
|
||||||
|
return emmcDumpBoot(right);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return emmcDumpSpecific(left, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int part_mmc_restorePart(){
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (parseStringInput(argv[0], &path))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (currentlyMounted < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return mmcFlashFile(path, currentlyMounted);
|
||||||
|
}
|
||||||
|
|
||||||
str_fnc_struct functions[] = {
|
str_fnc_struct functions[] = {
|
||||||
{"printf", part_printf, 1},
|
{"printf", part_printf, 1},
|
||||||
{"printInt", part_print_int, 1},
|
{"printInt", part_print_int, 1},
|
||||||
@@ -490,6 +521,8 @@ str_fnc_struct functions[] = {
|
|||||||
{"fs_combinePath", part_fs_combinePath, 3},
|
{"fs_combinePath", part_fs_combinePath, 3},
|
||||||
{"mmc_connect", part_ConnectMMC, 1},
|
{"mmc_connect", part_ConnectMMC, 1},
|
||||||
{"mmc_mount", part_MountMMC, 1},
|
{"mmc_mount", part_MountMMC, 1},
|
||||||
|
{"mmc_dumpPart", part_mmc_dumpPart, 2},
|
||||||
|
{"mmc_restorePart", part_mmc_restorePart, 1},
|
||||||
{"pause", part_Pause, 0},
|
{"pause", part_Pause, 0},
|
||||||
{"wait", part_Wait, 1},
|
{"wait", part_Wait, 1},
|
||||||
{"exit", part_Exit, 0},
|
{"exit", part_Exit, 0},
|
||||||
|
|||||||
Reference in New Issue
Block a user