mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 19:31:12 +00:00
Add partial dumping when free space is not enough
This commit is contained in:
parent
724970f795
commit
0a426db985
2 changed files with 121 additions and 10 deletions
|
@ -15,7 +15,7 @@
|
||||||
/ and optional writing functions as well. */
|
/ and optional writing functions as well. */
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_MINIMIZE 3
|
#define FF_FS_MINIMIZE 0
|
||||||
/* This option defines minimization level to remove some basic API functions.
|
/* This option defines minimization level to remove some basic API functions.
|
||||||
/
|
/
|
||||||
/ 0: Basic functions are fully enabled.
|
/ 0: Basic functions are fully enabled.
|
||||||
|
@ -200,7 +200,7 @@
|
||||||
/ disk_ioctl() function. */
|
/ disk_ioctl() function. */
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_NOFSINFO 0
|
#define FF_FS_NOFSINFO 1
|
||||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||||
/ option, and f_getfree() function at first time after volume mount will force
|
/ option, and f_getfree() function at first time after volume mount will force
|
||||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||||
|
|
127
ipl/main.c
127
ipl/main.c
|
@ -388,12 +388,63 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||||
{
|
{
|
||||||
static const u32 FAT32_FILESIZE_LIMIT = 0xFFFFFFFF;
|
static const u32 FAT32_FILESIZE_LIMIT = 0xFFFFFFFF;
|
||||||
static const u32 MULTIPART_SPLIT_SIZE = (1u << 31);
|
static const u32 MULTIPART_SPLIT_SIZE = (1u << 31);
|
||||||
|
static const u32 SECTORS_TO_MB_COEFF = 0x800;
|
||||||
|
|
||||||
u32 totalSectors = part->lba_end - part->lba_start + 1;
|
u32 totalSectors = part->lba_end - part->lba_start + 1;
|
||||||
|
u32 currPartIdx = 0;
|
||||||
|
u32 numSplitParts = 0;
|
||||||
|
u32 maxSplitParts = 0;
|
||||||
|
int isSmallSdCard = 0;
|
||||||
|
int partialDumpInProgress = 0;
|
||||||
char* outFilename = sd_path;
|
char* outFilename = sd_path;
|
||||||
u32 sdPathLen = strlen(sd_path);
|
u32 sdPathLen = strlen(sd_path);
|
||||||
u32 numSplitParts = 0;
|
|
||||||
if ((sd_fs.fs_type != FS_EXFAT) && totalSectors > (FAT32_FILESIZE_LIMIT/NX_EMMC_BLOCKSIZE))
|
FIL partialIdxFp;
|
||||||
|
char partialIdxFilename[12];
|
||||||
|
memcpy(partialIdxFilename, "partial.idx", 11);
|
||||||
|
partialIdxFilename[11] = 0;
|
||||||
|
|
||||||
|
gfx_printf(&gfx_con, "SD Card free space: %dMB, Total dump size %dMB\n",
|
||||||
|
sd_fs.free_clst * sd_fs.csize / SECTORS_TO_MB_COEFF,
|
||||||
|
totalSectors / SECTORS_TO_MB_COEFF);
|
||||||
|
|
||||||
|
// Check if the USER partition or the RAW eMMC fits the sd card free space
|
||||||
|
if (totalSectors > (sd_fs.free_clst * sd_fs.csize))
|
||||||
|
{
|
||||||
|
isSmallSdCard = 1;
|
||||||
|
|
||||||
|
gfx_printf(&gfx_con, "%kSD card free space is smaller than dump total size.%k\n", 0xFF00BAFF, 0xFFFFFFFF);
|
||||||
|
|
||||||
|
maxSplitParts = (sd_fs.free_clst * sd_fs.csize) / (MULTIPART_SPLIT_SIZE / 512);
|
||||||
|
|
||||||
|
if (!maxSplitParts)
|
||||||
|
{
|
||||||
|
gfx_printf(&gfx_con, "%kNot enough free space for partial dumping.%k\n", 0xFF0000FF, 0xFFFFFFFF);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if we continueing a previous raw eMMC dump in progress.
|
||||||
|
if (isSmallSdCard)
|
||||||
|
{
|
||||||
|
if (f_open(&partialIdxFp, partialIdxFilename, FA_READ) == FR_OK)
|
||||||
|
{
|
||||||
|
gfx_printf(&gfx_con, "%kFound partial dump in progress. Continuing...%k\n", 0xFF14FDAE, 0xFFFFFFFF);
|
||||||
|
|
||||||
|
partialDumpInProgress = 1;
|
||||||
|
|
||||||
|
f_read(&partialIdxFp, &currPartIdx, 4, NULL);
|
||||||
|
f_close(&partialIdxFp);
|
||||||
|
|
||||||
|
// Increase maxSplitParts to accommodate previously dumped parts
|
||||||
|
maxSplitParts += currPartIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gfx_printf(&gfx_con, "%kContinuing with partial dumping...%k\n", 0xFF00BAFF, 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if filesystem is FAT32 or the free space is smaller and dump in parts
|
||||||
|
if (((sd_fs.fs_type != FS_EXFAT) || isSmallSdCard) && totalSectors > (FAT32_FILESIZE_LIMIT/NX_EMMC_BLOCKSIZE))
|
||||||
{
|
{
|
||||||
static const u32 MULTIPART_SPLIT_SECTORS = MULTIPART_SPLIT_SIZE/NX_EMMC_BLOCKSIZE;
|
static const u32 MULTIPART_SPLIT_SECTORS = MULTIPART_SPLIT_SIZE/NX_EMMC_BLOCKSIZE;
|
||||||
numSplitParts = (totalSectors+MULTIPART_SPLIT_SECTORS-1)/MULTIPART_SPLIT_SECTORS;
|
numSplitParts = (totalSectors+MULTIPART_SPLIT_SECTORS-1)/MULTIPART_SPLIT_SECTORS;
|
||||||
|
@ -402,14 +453,28 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||||
memcpy(outFilename, sd_path, sdPathLen);
|
memcpy(outFilename, sd_path, sdPathLen);
|
||||||
outFilename[sdPathLen++] = '.';
|
outFilename[sdPathLen++] = '.';
|
||||||
|
|
||||||
outFilename[sdPathLen] = '0';
|
if (!partialDumpInProgress)
|
||||||
if (numSplitParts >= 10)
|
|
||||||
{
|
{
|
||||||
outFilename[sdPathLen+1] = '0';
|
outFilename[sdPathLen] = '0';
|
||||||
outFilename[sdPathLen+2] = 0;
|
if (numSplitParts >= 10)
|
||||||
|
{
|
||||||
|
outFilename[sdPathLen+1] = '0';
|
||||||
|
outFilename[sdPathLen+2] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
outFilename[sdPathLen+1] = 0;
|
||||||
}
|
}
|
||||||
|
// Continue from where we left, if partial dump in proggress.
|
||||||
else
|
else
|
||||||
outFilename[sdPathLen+1] = 0;
|
{
|
||||||
|
if (numSplitParts >= 10 && currPartIdx < 10)
|
||||||
|
{
|
||||||
|
outFilename[sdPathLen] = '0';
|
||||||
|
itoa(currPartIdx, &outFilename[sdPathLen+1], 10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FIL fp;
|
FIL fp;
|
||||||
|
@ -421,8 +486,15 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||||
|
|
||||||
u32 lba_curr = part->lba_start;
|
u32 lba_curr = part->lba_start;
|
||||||
u32 bytesWritten = 0;
|
u32 bytesWritten = 0;
|
||||||
u32 currPartIdx = 0;
|
|
||||||
u32 prevPct=200;
|
u32 prevPct=200;
|
||||||
|
|
||||||
|
// Continue from where we left, if partial dump in proggress.
|
||||||
|
if (partialDumpInProgress)
|
||||||
|
{
|
||||||
|
lba_curr += currPartIdx * (MULTIPART_SPLIT_SIZE / NX_EMMC_BLOCKSIZE);
|
||||||
|
totalSectors -= currPartIdx * (MULTIPART_SPLIT_SIZE / NX_EMMC_BLOCKSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
while(totalSectors > 0)
|
while(totalSectors > 0)
|
||||||
{
|
{
|
||||||
if (numSplitParts != 0 && bytesWritten >= MULTIPART_SPLIT_SIZE)
|
if (numSplitParts != 0 && bytesWritten >= MULTIPART_SPLIT_SIZE)
|
||||||
|
@ -439,6 +511,33 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||||
else
|
else
|
||||||
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
itoa(currPartIdx, &outFilename[sdPathLen], 10);
|
||||||
|
|
||||||
|
// More parts to dump that do not currently fit the sd card free space
|
||||||
|
if (isSmallSdCard && currPartIdx >= maxSplitParts)
|
||||||
|
{
|
||||||
|
// Create partial dump index file
|
||||||
|
if (f_open(&partialIdxFp, partialIdxFilename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
|
||||||
|
{
|
||||||
|
f_write(&partialIdxFp, &currPartIdx, 4, NULL);
|
||||||
|
f_close(&partialIdxFp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gfx_printf(&gfx_con, "%k\nError creating partial.idx file.%k\n", 0xFF0000FF, 0xFFFFFFFF);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_puts(&gfx_con, "\n1. Press any key and Power Switch from main menu.\n\
|
||||||
|
2. Move the files from SD card to free space.\n \
|
||||||
|
Don\'t move the partial.idx file!\n\
|
||||||
|
3. Unplug and re-plug USB while pressing Vol+.\n\
|
||||||
|
4. Run hekate - ipl again and press Dump RAW eMMC to continue");
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (f_open(&fp, outFilename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
|
if (f_open(&fp, outFilename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
|
||||||
{
|
{
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -482,6 +581,13 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
||||||
out:;
|
out:;
|
||||||
free(buf);
|
free(buf);
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
// Partial dump done. Remove partial dump index file.
|
||||||
|
if(partialDumpInProgress)
|
||||||
|
{
|
||||||
|
f_unlink(partialIdxFilename);
|
||||||
|
gfx_printf(&gfx_con, "\n\nYou can now join the files and get the complete raw eMMC dump.\n");
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,6 +609,11 @@ static void dump_emmc_selected(dumpType_t dumpType)
|
||||||
gfx_printf(&gfx_con, "%kFailed to mount SD card (make sure that it is inserted).%k\n", 0xFF0000FF, 0xFFFFFFFF);
|
gfx_printf(&gfx_con, "%kFailed to mount SD card (make sure that it is inserted).%k\n", 0xFF0000FF, 0xFFFFFFFF);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get SD Card free space for partial dumping
|
||||||
|
f_getfree("", &sd_fs.free_clst, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
|
|
Loading…
Reference in a new issue