emunand: Use HOS archive style for rawnand parts

This commit is contained in:
hexkyz 2019-04-28 18:22:32 +01:00
parent a9afbd2458
commit 0177b612f4
6 changed files with 59 additions and 7 deletions

View file

@ -104,7 +104,8 @@ int emu_device_partition_read_data(device_partition_t *devpart, void *dst, uint6
} }
} }
snprintf(target_path, sizeof(target_path) - 1, "%s%02d", origin_path, target_part); /* Treat the path as a folder with each part inside. */
snprintf(target_path, sizeof(target_path) - 1, "%s/%02d", origin_path, target_part);
} else { } else {
target_sector = sector; target_sector = sector;
strcpy(target_path, origin_path); strcpy(target_path, origin_path);
@ -176,7 +177,8 @@ int emu_device_partition_write_data(device_partition_t *devpart, const void *src
} }
} }
snprintf(target_path, sizeof(target_path) - 1, "%s%02d", origin_path, target_part); /* Treat the path as a folder with each part inside. */
snprintf(target_path, sizeof(target_path) - 1, "%s/%02d", origin_path, target_part);
} else { } else {
target_sector = sector; target_sector = sector;
strcpy(target_path, origin_path); strcpy(target_path, origin_path);

View file

@ -300,6 +300,21 @@ int fsdev_unmount_all(void) {
return 0; return 0;
} }
int fsdev_set_attr(const char *file, int attr, int mask) {
return fsdev_convert_rc(NULL, f_chmod(file, (BYTE)attr, (BYTE)mask));
}
int fsdev_get_attr(const char *file) {
FILINFO info;
FRESULT rc = f_stat(file, &info);
if (rc == FR_OK) {
return info.fattrib;
}
return fsdev_convert_rc(NULL, rc);
}
/* Adapted from https://github.com/benemorius/openOBC-devboard/blob/bf0a4a33e22d24e7c299f921d185da27377310e0/lib/fatfs/FatFS.cpp#L173 */ /* Adapted from https://github.com/benemorius/openOBC-devboard/blob/bf0a4a33e22d24e7c299f921d185da27377310e0/lib/fatfs/FatFS.cpp#L173 */
static int fsdev_convert_rc(struct _reent *r, FRESULT rc) { static int fsdev_convert_rc(struct _reent *r, FRESULT rc) {
int errornumber; int errornumber;

View file

@ -27,6 +27,9 @@ int fsdev_register_device(const char *name);
int fsdev_unregister_device(const char *name); int fsdev_unregister_device(const char *name);
int fsdev_unmount_device(const char *name); /* also unregisters. */ int fsdev_unmount_device(const char *name); /* also unregisters. */
int fsdev_set_attr(const char *file, int attr, int mask); /* Non-standard function to set file DOS attributes. */
int fsdev_get_attr(const char *file); /* Non-standard function to get file DOS attributes. */
int fsdev_set_default_device(const char *name); /* must be registered. */ int fsdev_set_default_device(const char *name); /* must be registered. */
int fsdev_is_exfat(const char *name); /* must be registered. */ int fsdev_is_exfat(const char *name); /* must be registered. */

View file

@ -50,7 +50,7 @@
/* This option switches f_expand function. (0:Disable or 1:Enable) */ /* This option switches f_expand function. (0:Disable or 1:Enable) */
#define FF_USE_CHMOD 0 #define FF_USE_CHMOD 1
/* This option switches attribute manipulation functions, f_chmod() and f_utime(). /* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ / (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */

View file

@ -230,11 +230,12 @@ static bool nxboot_configure_emunand() {
/* Check if full rawnand image file is present. */ /* Check if full rawnand image file is present. */
if (!is_valid_file(emunand_rawnand_base_path)) { if (!is_valid_file(emunand_rawnand_base_path)) {
char emunand_rawnand_path[0x300 + 3 + 1] = {0}; char emunand_rawnand_path[0x300 + 4 + 1] = {0};
/* Search for rawnand part files instead. */ /* Search for rawnand part files instead. */
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
snprintf(emunand_rawnand_path, sizeof(emunand_rawnand_path) - 1, "%s%02d", emunand_rawnand_base_path, i); /* Treat rawnand as a folder with each part inside. */
snprintf(emunand_rawnand_path, sizeof(emunand_rawnand_path) - 1, "%s/%02d", emunand_rawnand_base_path, i);
if (is_valid_file(emunand_rawnand_path)) { if (is_valid_file(emunand_rawnand_path)) {
if (i == 0) { if (i == 0) {
/* The size of the first part file should tell us the part limit. */ /* The size of the first part file should tell us the part limit. */

View file

@ -26,6 +26,8 @@
#include "utils.h" #include "utils.h"
#include "sdmmc/sdmmc.h" #include "sdmmc/sdmmc.h"
#include "lib/fatfs/ff.h"
static bool g_ahb_redirect_enabled = false; static bool g_ahb_redirect_enabled = false;
static bool g_sd_device_initialized = false; static bool g_sd_device_initialized = false;
static bool g_emmc_device_initialized = false; static bool g_emmc_device_initialized = false;
@ -154,6 +156,7 @@ static int mmc_partition_write(device_partition_t *devpart, const void *src, uin
} }
static int emummc_partition_initialize(device_partition_t *devpart) { static int emummc_partition_initialize(device_partition_t *devpart) {
/* Allocate the crypto work buffer. */
if ((devpart->read_cipher != NULL) || (devpart->write_cipher != NULL)) { if ((devpart->read_cipher != NULL) || (devpart->write_cipher != NULL)) {
devpart->crypto_work_buffer = memalign(16, devpart->sector_size * 16); devpart->crypto_work_buffer = memalign(16, devpart->sector_size * 16);
if (devpart->crypto_work_buffer == NULL) { if (devpart->crypto_work_buffer == NULL) {
@ -166,12 +169,16 @@ static int emummc_partition_initialize(device_partition_t *devpart) {
devpart->crypto_work_buffer_num_sectors = 0; devpart->crypto_work_buffer_num_sectors = 0;
} }
devpart->initialized = true; devpart->initialized = true;
return 0; return 0;
} }
static void emummc_partition_finalize(device_partition_t *devpart) { static void emummc_partition_finalize(device_partition_t *devpart) {
/* Free the crypto work buffer. */
if (devpart->crypto_work_buffer != NULL) {
free(devpart->crypto_work_buffer); free(devpart->crypto_work_buffer);
} }
}
static int nxfs_bis_crypto_decrypt(device_partition_t *devpart, uint64_t sector, uint64_t num_sectors) { static int nxfs_bis_crypto_decrypt(device_partition_t *devpart, uint64_t sector, uint64_t num_sectors) {
unsigned int keyslot_a = 4; /* These keyslots are never used by exosphere, and should be safe. */ unsigned int keyslot_a = 4; /* These keyslots are never used by exosphere, and should be safe. */
@ -566,6 +573,30 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot
model.num_sectors = (256ull << 30) / model.sector_size; model.num_sectors = (256ull << 30) / model.sector_size;
if (!is_exfat) { if (!is_exfat) {
/* For multiple parts we want a folder with the archive bit set. */
rc = fsdev_get_attr(emunand_rawnand_base_path);
/* Failed to get file DOS attributes. */
if (rc == -1) {
return -1;
}
/* Our path is not a directory. */
if (!(rc & AM_DIR)) {
return -1;
}
/* Check if the archive bit is not set. */
if (!(rc & AM_ARC)) {
/* Try to set the archive bit. */
rc = fsdev_set_attr(emunand_rawnand_base_path, AM_ARC, AM_ARC);
/* Failed to set file DOS attributes. */
if (rc == -1) {
return -1;
}
}
/* Mount emulated raw NAND device from multiple parts. */ /* Mount emulated raw NAND device from multiple parts. */
rc = emudev_mount_device_multipart("rawnand", &model, emunand_rawnand_base_path, num_parts, part_limit); rc = emudev_mount_device_multipart("rawnand", &model, emunand_rawnand_base_path, num_parts, part_limit);