1
0
Fork 0
mirror of https://github.com/suchmememanyskill/TegraExplorer.git synced 2024-11-25 13:22:04 +00:00

add partition flashing

This commit is contained in:
suchmememanyskill 2020-12-31 12:55:26 +01:00
parent db2e115fb0
commit cd6bf6ad9d
7 changed files with 129 additions and 13 deletions

View file

@ -28,7 +28,9 @@ const char *TEErrors[] = {
[TE_ERR_PARTITION_NOT_FOUND - 1] = "Failed to find partition", [TE_ERR_PARTITION_NOT_FOUND - 1] = "Failed to find partition",
[TE_ERR_PATH_IN_PATH - 1] = "Can't move/copy folder into itself", [TE_ERR_PATH_IN_PATH - 1] = "Can't move/copy folder into itself",
[TE_ERR_EMMC_READ_FAIL - 1] = "Emmc/Emummc read failed", [TE_ERR_EMMC_READ_FAIL - 1] = "Emmc/Emummc read failed",
[TE_ERR_EMMC_WRITE_FAIL - 1] = "Emmc/Emummc write failed",
[TE_ERR_NO_SD - 1] = "No sd detected", [TE_ERR_NO_SD - 1] = "No sd detected",
[TE_ERR_FILE_TOO_BIG_FOR_DEST - 1] = "File is too big for dest",
}; };
const char *GetErrStr(u32 err){ const char *GetErrStr(u32 err){

View file

@ -20,6 +20,10 @@ enum {
TE_ERR_EMMC_READ_FAIL, TE_ERR_EMMC_READ_FAIL,
TE_ERR_EMMC_WRITE_FAIL, TE_ERR_EMMC_WRITE_FAIL,
TE_ERR_NO_SD, TE_ERR_NO_SD,
TE_ERR_FILE_TOO_BIG_FOR_DEST,
TE_ERR_MEM_ALLOC_FAIL,
TE_WARN_FILE_EXISTS,
TE_WARN_FILE_TOO_SMALL_FOR_DEST,
}; };
#define newErrCode(err) (ErrCode_t) {err, __LINE__, __FILE__} #define newErrCode(err) (ErrCode_t) {err, __LINE__, __FILE__}

View file

@ -47,7 +47,7 @@ char *GetFileAttribs(FSEntry_t entry){
return ret; return ret;
} }
bool FileExists(char* path){ bool FileExists(const char* path){
FRESULT fr; FRESULT fr;
FILINFO fno; FILINFO fno;

View file

@ -6,4 +6,4 @@ FSEntry_t GetFileInfo(const char *path);
char *EscapeFolder(const char *current); char *EscapeFolder(const char *current);
char *CombinePaths(const char *current, const char *add); char *CombinePaths(const char *current, const char *add);
char *GetFileAttribs(FSEntry_t entry); char *GetFileAttribs(FSEntry_t entry);
bool FileExists(char* path); bool FileExists(const char* path);

View file

@ -11,14 +11,19 @@
#include "../hid/hid.h" #include "../hid/hid.h"
#include <storage/nx_sd.h> #include <storage/nx_sd.h>
#include <string.h> #include <string.h>
#include "../fs/fsutils.h"
// Uses default storage in nx_emmc.c // Uses default storage in nx_emmc.c
// Expects the correct mmc & partition to be set // Expects the correct mmc & partition to be set
ErrCode_t EmmcDumpToFile(const char *path, u32 lba_start, u32 lba_end){ ErrCode_t EmmcDumpToFile(const char *path, u32 lba_start, u32 lba_end, u8 force){
FIL fp; FIL fp;
u32 curLba = lba_start; u32 curLba = lba_start;
u32 totalSectors = lba_end - lba_start + 1; u32 totalSectors = lba_end - lba_start + 1;
if (FileExists(path) && !force){
return newErrCode(TE_WARN_FILE_EXISTS);
}
int res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE); int res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE);
if (res){ if (res){
return newErrCode(res); return newErrCode(res);
@ -28,6 +33,9 @@ ErrCode_t EmmcDumpToFile(const char *path, u32 lba_start, u32 lba_end){
u8 *buff = malloc(TConf.FSBuffSize); u8 *buff = malloc(TConf.FSBuffSize);
if (!buff)
return newErrCode(TE_ERR_MEM_ALLOC_FAIL);
u32 x, y; u32 x, y;
gfx_con_getpos(&x, &y); gfx_con_getpos(&x, &y);
@ -56,21 +64,74 @@ ErrCode_t EmmcDumpToFile(const char *path, u32 lba_start, u32 lba_end){
return err; return err;
} }
ErrCode_t DumpEmmcPart(const char *path, const char *part){ ErrCode_t EmmcRestoreFromFile(const char *path, u32 lba_start, u32 lba_end, u8 force){
FIL fp;
u32 curLba = lba_start;
u32 totalSectorsDest = lba_end - lba_start + 1;
int res = f_open(&fp, path, FA_OPEN_ALWAYS | FA_READ);
if (res)
return newErrCode(res);
u64 totalSizeSrc = f_size(&fp);
u32 totalSectorsSrc = totalSizeSrc / NX_EMMC_BLOCKSIZE;
if (totalSectorsSrc > totalSectorsDest) // We don't close the file here, oh well
return newErrCode(TE_ERR_FILE_TOO_BIG_FOR_DEST);
if (totalSectorsSrc < totalSectorsDest && !force)
return newErrCode(TE_WARN_FILE_TOO_SMALL_FOR_DEST);
u8 *buff = malloc(TConf.FSBuffSize);
ErrCode_t err = newErrCode(0);
if (!buff)
return newErrCode(TE_ERR_MEM_ALLOC_FAIL);
u32 x, y;
gfx_con_getpos(&x, &y);
while (totalSectorsSrc > 0){
u32 num = MIN(totalSectorsSrc, TConf.FSBuffSize / NX_EMMC_BLOCKSIZE);
if ((res = f_read(&fp, buff, num * NX_EMMC_BLOCKSIZE, NULL))){
err = newErrCode(res);
break;
}
if (!emummc_storage_write(&emmc_storage, curLba, num, buff)){
err = newErrCode(TE_ERR_EMMC_WRITE_FAIL);
break;
}
curLba += num;
totalSectorsSrc -= num;
u32 percent = ((curLba - lba_start) * 100) / ((totalSizeSrc / NX_EMMC_BLOCKSIZE));
gfx_printf("[%3d%%]", percent);
gfx_con_setpos(x, y);
}
f_close(&fp);
free(buff);
return err;
}
ErrCode_t DumpOrWriteEmmcPart(const char *path, const char *part, u8 write, u8 force){
const u32 BOOT_PART_SIZE = emmc_storage.ext_csd.boot_mult << 17; const u32 BOOT_PART_SIZE = emmc_storage.ext_csd.boot_mult << 17;
u32 lba_start = 0;
u32 lba_end = 0;
if (!sd_mount()) if (!sd_mount())
return newErrCode(TE_ERR_NO_SD); return newErrCode(TE_ERR_NO_SD);
// maybe check for existing file here
if (!memcmp(part, "BOOT0", 5)){ if (!memcmp(part, "BOOT0", 5)){
emummc_storage_set_mmc_partition(&emmc_storage, 1); emummc_storage_set_mmc_partition(&emmc_storage, 1);
return EmmcDumpToFile(path, 0, (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1); lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
} }
else if (!memcmp(part, "BOOT1", 5)){ else if (!memcmp(part, "BOOT1", 5)){
emummc_storage_set_mmc_partition(&emmc_storage, 2); emummc_storage_set_mmc_partition(&emmc_storage, 2);
return EmmcDumpToFile(path, 0, (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1); lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
} }
else { else {
emummc_storage_set_mmc_partition(&emmc_storage, 0); emummc_storage_set_mmc_partition(&emmc_storage, 0);
@ -79,6 +140,9 @@ ErrCode_t DumpEmmcPart(const char *path, const char *part){
if (!system_part) if (!system_part)
return newErrCode(TE_ERR_PARTITION_NOT_FOUND); return newErrCode(TE_ERR_PARTITION_NOT_FOUND);
return EmmcDumpToFile(path, system_part->lba_start, system_part->lba_end); lba_start = system_part->lba_start;
lba_end = system_part->lba_end;
} }
return ((write) ? EmmcRestoreFromFile(path, lba_start, lba_end, force) : EmmcDumpToFile(path, lba_start, lba_end, force));
} }

View file

@ -1,4 +1,4 @@
#pragma once #pragma once
#include "../err.h" #include "../err.h"
ErrCode_t DumpEmmcPart(const char *path, const char *part); ErrCode_t DumpOrWriteEmmcPart(const char *path, const char *part, u8 write, u8 force);

View file

@ -14,6 +14,7 @@
#include "emmcfile.h" #include "emmcfile.h"
#include <storage/nx_sd.h> #include <storage/nx_sd.h>
#include "../fs/fsutils.h" #include "../fs/fsutils.h"
#include "../utils/utils.h"
MenuEntry_t GptMenuHeader[] = { MenuEntry_t GptMenuHeader[] = {
{.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "<- Back"}, {.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "<- Back"},
@ -33,6 +34,8 @@ void GptMenu(u8 MMCType){
if (connectMMC(MMCType)) if (connectMMC(MMCType))
return; return;
GptMenuHeader[1].optionUnion = (TConf.explorerCopyMode == CMODE_Copy) ? (COLORTORGB(COLOR_ORANGE)) : (COLORTORGB(COLOR_GREY) | SKIPBIT);
Vector_t GptMenu = newVec(sizeof(MenuEntry_t), 15); Vector_t GptMenu = newVec(sizeof(MenuEntry_t), 15);
GptMenu.count = ARR_LEN(GptMenuHeader); GptMenu.count = ARR_LEN(GptMenuHeader);
memcpy(GptMenu.data, GptMenuHeader, sizeof(MenuEntry_t) * ARR_LEN(GptMenuHeader)); memcpy(GptMenu.data, GptMenuHeader, sizeof(MenuEntry_t) * ARR_LEN(GptMenuHeader));
@ -74,9 +77,40 @@ void GptMenu(u8 MMCType){
res = newMenu(&GptMenu, res, 40, 20, ALWAYSREDRAW | ENABLEB, GptMenu.count); res = newMenu(&GptMenu, res, 40, 20, ALWAYSREDRAW | ENABLEB, GptMenu.count);
if (res < 2){ if (res < 1){
break; break;
} }
else if (res == 1){
gfx_clearscreen();
char *fileName = CpyStr(strrchr(TConf.srcCopy, '/') + 1);
for (int i = 0; i < strlen(fileName); i++){
if (fileName[i] >= 'a' && fileName[i] <= 'z')
fileName[i] &= ~BIT(5);
}
gfx_printf("Are you sure you want to flash %s? ", fileName);
if (MakeYesNoHorzMenu(3, COLOR_DEFAULT)){
RESETCOLOR;
gfx_printf("\nFlashing %s... ", fileName);
ErrCode_t a = DumpOrWriteEmmcPart(TConf.srcCopy, fileName, 1, 0);
if (a.err){
if (a.err == TE_WARN_FILE_TOO_SMALL_FOR_DEST){
gfx_printf("\r%s is too small for the destination. Flash anyway? ", fileName);
if (MakeYesNoHorzMenu(3, COLOR_DEFAULT)){
RESETCOLOR;
gfx_printf("\nFlashing %s... ", fileName);
a = DumpOrWriteEmmcPart(TConf.srcCopy, fileName, 1, 1);
}
else {
a.err = 0;
}
}
DrawError(a);
}
}
free(fileName);
}
else if (entries[res].icon == 127){ else if (entries[res].icon == 127){
unmountMMCPart(); unmountMMCPart();
ErrCode_t err = mountMMCPart(entries[res].name); ErrCode_t err = mountMMCPart(entries[res].name);
@ -107,9 +141,21 @@ void GptMenu(u8 MMCType){
char *path = CombinePaths("sd:/tegraexplorer/Dumps", entries[res].name); char *path = CombinePaths("sd:/tegraexplorer/Dumps", entries[res].name);
ErrCode_t a = DumpEmmcPart(path, entries[res].name); ErrCode_t a = DumpOrWriteEmmcPart(path, entries[res].name, 0, 0);
if (a.err) if (a.err){
if (a.err == TE_WARN_FILE_EXISTS){
gfx_printf("\rDest file for %s exists already. Overwrite? ", entries[res].name);
if (MakeYesNoHorzMenu(3, COLOR_DEFAULT)){
RESETCOLOR;
gfx_printf("\nDumping %s... ", entries[res].name);
a = DumpOrWriteEmmcPart(path, entries[res].name, 0, 1);
}
else {
a.err = 0;
}
}
DrawError(a); DrawError(a);
}
} }
} }
} }