From 0986b48a554db8d0d60a9b91c4c6beedb3112f39 Mon Sep 17 00:00:00 2001 From: hexkyz Date: Sun, 9 Jun 2019 19:33:44 +0100 Subject: [PATCH] emummc: implement SD partition mode; clean up and rename emunand code --- common/defaults/BCT.ini | 6 +- fusee/fusee-secondary/src/device_partition.c | 108 ++++++------- fusee/fusee-secondary/src/device_partition.h | 3 + fusee/fusee-secondary/src/emu_dev.c | 6 +- fusee/fusee-secondary/src/nxboot.c | 116 +++++++------- fusee/fusee-secondary/src/nxboot.h | 8 +- fusee/fusee-secondary/src/nxfs.c | 158 ++++++++++++++++--- fusee/fusee-secondary/src/nxfs.h | 5 +- 8 files changed, 274 insertions(+), 136 deletions(-) diff --git a/common/defaults/BCT.ini b/common/defaults/BCT.ini index e3ade4efb..679419f9c 100644 --- a/common/defaults/BCT.ini +++ b/common/defaults/BCT.ini @@ -4,9 +4,9 @@ stage2_path = atmosphere/fusee-secondary.bin stage2_addr = 0xF0000000 stage2_entrypoint = 0xF0000000 -[emunand] -emunand_enabled = 0 -emunand_path = atmosphere/emunand +[emummc] +emummc_enabled = 0 +emummc_path = atmosphere/emummc [exosphere] ; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future. diff --git a/fusee/fusee-secondary/src/device_partition.c b/fusee/fusee-secondary/src/device_partition.c index cf15fe171..940ae985f 100644 --- a/fusee/fusee-secondary/src/device_partition.c +++ b/fusee/fusee-secondary/src/device_partition.c @@ -88,27 +88,33 @@ int emu_device_partition_read_data(device_partition_t *devpart, void *dst, uint6 } } - /* Handle data in multiple parts, if necessary. */ - if (num_parts > 0) { - int target_part = 0; - uint64_t data_offset = sector * devpart->sector_size; - - if (data_offset >= part_limit) { - uint64_t data_offset_aligned = (data_offset + (part_limit - 1)) & ~(part_limit - 1); - target_part = (data_offset_aligned == data_offset) ? (data_offset / part_limit) : (data_offset_aligned / part_limit) - 1; - target_sector = (data_offset - (target_part * part_limit)) / devpart->sector_size; + /* Prepare the right file path if using file mode. */ + if (devpart->emu_use_file && (origin_path != NULL)) { + /* Handle data in multiple parts, if necessary. */ + if (num_parts > 0) { + int target_part = 0; + uint64_t data_offset = sector * devpart->sector_size; - /* Target part is invalid. */ - if (target_part > num_parts) { - return -1; + if (data_offset >= part_limit) { + uint64_t data_offset_aligned = (data_offset + (part_limit - 1)) & ~(part_limit - 1); + target_part = (data_offset_aligned == data_offset) ? (data_offset / part_limit) : (data_offset_aligned / part_limit) - 1; + target_sector = (data_offset - (target_part * part_limit)) / devpart->sector_size; + + /* Target part is invalid. */ + if (target_part > num_parts) { + return -1; + } } + + /* Treat the path as a folder with each part inside. */ + snprintf(target_path, sizeof(target_path) - 1, "%s/%02d", origin_path, target_part); + } else { + target_sector = sector; + strcpy(target_path, origin_path); } - /* Treat the path as a folder with each part inside. */ - snprintf(target_path, sizeof(target_path) - 1, "%s/%02d", origin_path, target_part); - } else { - target_sector = sector; - strcpy(target_path, origin_path); + /* Update the target file path. */ + devpart->emu_file_path = target_path; } /* Read the partition data. */ @@ -116,11 +122,8 @@ int emu_device_partition_read_data(device_partition_t *devpart, void *dst, uint6 for (uint64_t i = 0; i < num_sectors; i += devpart->crypto_work_buffer_num_sectors) { uint64_t n = (i + devpart->crypto_work_buffer_num_sectors > num_sectors) ? (num_sectors - i) : devpart->crypto_work_buffer_num_sectors; - /* Read partition data using our backing file. */ - FILE *origin = fopen(target_path, "rb"); - fseek(origin, (target_sector + i) * devpart->sector_size, SEEK_CUR); - rc = (fread(dst, devpart->sector_size, n, origin) > 0) ? 0 : -1; - fclose(origin); + /* Read partition data. */ + rc = devpart->reader(devpart, devpart->crypto_work_buffer, target_sector + i, n); if (rc != 0) { return rc; @@ -137,11 +140,8 @@ int emu_device_partition_read_data(device_partition_t *devpart, void *dst, uint6 memcpy(dst + (size_t)(devpart->sector_size * i), devpart->crypto_work_buffer, (size_t)(devpart->sector_size * n)); } } else { - /* Read partition data using our backing file. */ - FILE *origin = fopen(target_path, "rb"); - fseek(origin, target_sector * devpart->sector_size, SEEK_CUR); - rc = (fread(dst, devpart->sector_size, num_sectors, origin) > 0) ? 0 : -1; - fclose(origin); + /* Read partition data. */ + rc = devpart->reader(devpart, dst, target_sector, num_sectors); } return rc; @@ -161,27 +161,33 @@ int emu_device_partition_write_data(device_partition_t *devpart, const void *src } } - /* Handle data in multiple parts, if necessary. */ - if (num_parts > 0) { - int target_part = 0; - uint64_t data_offset = sector * devpart->sector_size; - - if (data_offset >= part_limit) { - uint64_t data_offset_aligned = (data_offset + (part_limit - 1)) & ~(part_limit - 1); - target_part = (data_offset_aligned == data_offset) ? (data_offset / part_limit) : (data_offset_aligned / part_limit) - 1; - target_sector = (data_offset - (target_part * part_limit)) / devpart->sector_size; + /* Prepare the right file path if using file mode. */ + if (devpart->emu_use_file && (origin_path != NULL)) { + /* Handle data in multiple parts, if necessary. */ + if (num_parts > 0) { + int target_part = 0; + uint64_t data_offset = sector * devpart->sector_size; - /* Target part is invalid. */ - if (target_part > num_parts) { - return -1; + if (data_offset >= part_limit) { + uint64_t data_offset_aligned = (data_offset + (part_limit - 1)) & ~(part_limit - 1); + target_part = (data_offset_aligned == data_offset) ? (data_offset / part_limit) : (data_offset_aligned / part_limit) - 1; + target_sector = (data_offset - (target_part * part_limit)) / devpart->sector_size; + + /* Target part is invalid. */ + if (target_part > num_parts) { + return -1; + } } + + /* Treat the path as a folder with each part inside. */ + snprintf(target_path, sizeof(target_path) - 1, "%s/%02d", origin_path, target_part); + } else { + target_sector = sector; + strcpy(target_path, origin_path); } - /* Treat the path as a folder with each part inside. */ - snprintf(target_path, sizeof(target_path) - 1, "%s/%02d", origin_path, target_part); - } else { - target_sector = sector; - strcpy(target_path, origin_path); + /* Update the target file path. */ + devpart->emu_file_path = target_path; } /* Write the partition data. */ @@ -199,22 +205,16 @@ int emu_device_partition_write_data(device_partition_t *devpart, const void *src return rc; } - /* Write partition data using our backing file. */ - FILE *origin = fopen(target_path, "wb"); - fseek(origin, (target_sector + i) * devpart->sector_size, SEEK_CUR); - rc = (fwrite(src, devpart->sector_size, n, origin) > 0) ? 0 : -1; - fclose(origin); + /* Write partition data. */ + rc = devpart->writer(devpart, devpart->crypto_work_buffer, target_sector + i, n); if (rc != 0) { return rc; } } } else { - /* Write partition data using our backing file. */ - FILE *origin = fopen(target_path, "wb"); - fseek(origin, sector * devpart->sector_size, SEEK_CUR); - rc = (fwrite(src, devpart->sector_size, num_sectors, origin) > 0) ? 0 : -1; - fclose(origin); + /* Write partition data. */ + rc = devpart->writer(devpart, src, sector, num_sectors); } return rc; diff --git a/fusee/fusee-secondary/src/device_partition.h b/fusee/fusee-secondary/src/device_partition.h index 6b4607e56..53b9c3df4 100644 --- a/fusee/fusee-secondary/src/device_partition.h +++ b/fusee/fusee-secondary/src/device_partition.h @@ -65,6 +65,9 @@ typedef struct device_partition_t { uint8_t __attribute__((aligned(16))) keys[DEVPART_KEY_MAX][DEVPART_KEY_MAX_SIZE]; /* Key. */ uint8_t __attribute__((aligned(16))) iv[DEVPART_IV_MAX_SIZE]; /* IV. */ bool initialized; + + char *emu_file_path; /* Emulated device file path. */ + bool emu_use_file; } device_partition_t; int device_partition_read_data(device_partition_t *devpart, void *dst, uint64_t sector, uint64_t num_sectors); diff --git a/fusee/fusee-secondary/src/emu_dev.c b/fusee/fusee-secondary/src/emu_dev.c index 9b49db619..df22a4951 100644 --- a/fusee/fusee-secondary/src/emu_dev.c +++ b/fusee/fusee-secondary/src/emu_dev.c @@ -114,7 +114,11 @@ int emudev_mount_device(const char *name, const device_partition_t *devpart, con strcpy(device->name, name); strcpy(device->root_path, name); strcat(device->root_path, ":/"); - strcpy(device->origin_path, origin_path); + + /* Copy the file path for file mode. */ + if (devpart->emu_use_file) + strcpy(device->origin_path, origin_path); + device->num_parts = 0; device->part_limit = 0; diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 29cf5237d..a88b18fcd 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -100,17 +100,21 @@ static const uint8_t dev_pkc_modulus[0x100] = { 0xD5, 0x52, 0xDA, 0xEC, 0x41, 0xA4, 0xAD, 0x7B, 0x36, 0x86, 0x18, 0xB4, 0x5B, 0xD1, 0x30, 0xBB }; -static int emunand_ini_handler(void *user, const char *section, const char *name, const char *value) { - emunand_config_t *emunand_cfg = (emunand_config_t *)user; - if (strcmp(section, "emunand") == 0) { - if (strcmp(name, EMUNAND_ENABLED_KEY) == 0) { +static int emummc_ini_handler(void *user, const char *section, const char *name, const char *value) { + emummc_config_t *emummc_cfg = (emummc_config_t *)user; + if (strcmp(section, "emummc") == 0) { + if (strcmp(name, EMUMMC_ENABLED_KEY) == 0) { int tmp = 0; sscanf(value, "%d", &tmp); - emunand_cfg->enabled = (tmp != 0); + emummc_cfg->enabled = (tmp != 0); } - if (strcmp(name, EMUNAND_PATH_KEY) == 0) { - strncpy(emunand_cfg->path, value, sizeof(emunand_cfg->path) - 1); - emunand_cfg->path[sizeof(emunand_cfg->path) - 1] = '\0'; + if (strcmp(name, EMUMMC_SECTOR_KEY) == 0) { + uint64_t sector = 0; + sscanf(value, "%llu", §or); + emummc_cfg->sector = sector; + } else if (strcmp(name, EMUMMC_PATH_KEY) == 0) { + strncpy(emummc_cfg->path, value, sizeof(emummc_cfg->path) - 1); + emummc_cfg->path[sizeof(emummc_cfg->path) - 1] = '\0'; } else { return 0; } @@ -204,59 +208,63 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) { } } -static bool nxboot_configure_emunand() { - emunand_config_t emunand_cfg = {.enabled = false, .path = ""}; +static bool nxboot_configure_emummc() { + emummc_config_t emummc_cfg = {.enabled = false, .sector = -1, .path = ""}; - /* Load emunand settings from BCT.ini file. */ - if (ini_parse_string(get_loader_ctx()->bct0, emunand_ini_handler, &emunand_cfg) < 0) { + /* Load emummc settings from BCT.ini file. */ + if (ini_parse_string(get_loader_ctx()->bct0, emummc_ini_handler, &emummc_cfg) < 0) { fatal_error("[NXBOOT] Failed to parse BCT.ini!\n"); } - if (emunand_cfg.enabled) { - int num_parts = 0; - uint64_t part_limit = 0; - char emunand_boot0_path[0x300 + 1] = {0}; - char emunand_boot1_path[0x300 + 1] = {0}; - char emunand_rawnand_path[0x300 + 1] = {0}; - - /* Check if the supplied path is valid. */ - if (!is_valid_folder(emunand_cfg.path)) { - fatal_error("[NXBOOT] Failed to find EmuNAND folder!\n"); - } - - /* Prepare expected file paths. */ - snprintf(emunand_boot0_path, sizeof(emunand_boot0_path) - 1, "sdmc:/%s/%s", emunand_cfg.path, "boot0"); - snprintf(emunand_boot1_path, sizeof(emunand_boot1_path) - 1, "sdmc:/%s/%s", emunand_cfg.path, "boot1"); - - /* Check if boot0 and boot1 image files are present. */ - if (!is_valid_file(emunand_boot0_path) || !is_valid_file(emunand_boot1_path)) { - fatal_error("[NXBOOT] Failed to find EmuNAND boot0/boot1 image files!\n"); - } - - /* Find raw image files (single or multi part). */ - for (int i = 0; i < 64; i++) { - snprintf(emunand_rawnand_path, sizeof(emunand_rawnand_path) - 1, "sdmc:/%s/%02d", emunand_cfg.path, i); - if (is_valid_file(emunand_rawnand_path)) { - if (i == 0) { - /* The size of the first file should tell us the part limit. */ - part_limit = get_file_size(emunand_rawnand_path); - } - num_parts++; + if (emummc_cfg.enabled) { + if (emummc_cfg.sector >= 0) { + /* Mount emulated NAND from SD card partition. */ + if (nxfs_mount_emummc_partition(emummc_cfg.sector) < 0) { + fatal_error("[NXBOOT] Failed to mount EmuMMC from SD card partition!\n"); } - } - - /* Check if at least one raw image file is present. */ - if ((num_parts == 0) || (part_limit == 0)) { - fatal_error("[NXBOOT] Failed to find EmuNAND raw image files!\n"); - } + } else if (is_valid_folder(emummc_cfg.path)) { + int num_parts = 0; + uint64_t part_limit = 0; + char emummc_boot0_path[0x300 + 1] = {0}; + char emummc_boot1_path[0x300 + 1] = {0}; + char emummc_rawnand_path[0x300 + 1] = {0}; - /* Mount emulated NAND. */ - if (nxfs_mount_emu_emmc(emunand_cfg.path, num_parts, part_limit) < 0) { - fatal_error("[NXBOOT] Failed to mount emulated eMMC!\n"); + /* Prepare expected file paths. */ + snprintf(emummc_boot0_path, sizeof(emummc_boot0_path) - 1, "sdmc:/%s/%s", emummc_cfg.path, "boot0"); + snprintf(emummc_boot1_path, sizeof(emummc_boot1_path) - 1, "sdmc:/%s/%s", emummc_cfg.path, "boot1"); + + /* Check if boot0 and boot1 image files are present. */ + if (!is_valid_file(emummc_boot0_path) || !is_valid_file(emummc_boot1_path)) { + fatal_error("[NXBOOT] Failed to find EmuMMC boot0/boot1 image files!\n"); + } + + /* Find raw image files (single or multi part). */ + for (int i = 0; i < 64; i++) { + snprintf(emummc_rawnand_path, sizeof(emummc_rawnand_path) - 1, "sdmc:/%s/%02d", emummc_cfg.path, i); + if (is_valid_file(emummc_rawnand_path)) { + if (i == 0) { + /* The size of the first file should tell us the part limit. */ + part_limit = get_file_size(emummc_rawnand_path); + } + num_parts++; + } + } + + /* Check if at least one raw image file is present. */ + if ((num_parts == 0) || (part_limit == 0)) { + fatal_error("[NXBOOT] Failed to find EmuMMC raw image files!\n"); + } + + /* Mount emulated NAND from files. */ + if (nxfs_mount_emummc_file(emummc_cfg.path, num_parts, part_limit) < 0) { + fatal_error("[NXBOOT] Failed to mount EmuMMC from files!\n"); + } + } else { + fatal_error("[NXBOOT] Invalid EmuMMC setting!\n"); } } - return emunand_cfg.enabled; + return emummc_cfg.enabled; } static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int keygen_type) { @@ -417,8 +425,8 @@ uint32_t nxboot_main(void) { FILE *boot0, *pk2file; void *exosphere_memaddr; - /* Configure emunand or mount the real NAND. */ - if (!nxboot_configure_emunand()) { + /* Configure emummc or mount the real NAND. */ + if (!nxboot_configure_emummc()) { if (nxfs_mount_emmc() < 0) { fatal_error("[NXBOOT] Failed to mount eMMC!\n"); } diff --git a/fusee/fusee-secondary/src/nxboot.h b/fusee/fusee-secondary/src/nxboot.h index 6daa0302d..3c4585d14 100644 --- a/fusee/fusee-secondary/src/nxboot.h +++ b/fusee/fusee-secondary/src/nxboot.h @@ -19,13 +19,15 @@ #include "utils.h" -#define EMUNAND_ENABLED_KEY "emunand_enabled" -#define EMUNAND_PATH_KEY "emunand_path" +#define EMUMMC_ENABLED_KEY "emummc_enabled" +#define EMUMMC_SECTOR_KEY "emummc_sector" +#define EMUMMC_PATH_KEY "emummc_path" typedef struct { bool enabled; + uint64_t sector; char path[0x100]; -} emunand_config_t; +} emummc_config_t; #define MAILBOX_NX_BOOTLOADER_BASE_100_620 0x40002E00 #define MAILBOX_NX_BOOTLOADER_BASE_700 0x40000000 diff --git a/fusee/fusee-secondary/src/nxfs.c b/fusee/fusee-secondary/src/nxfs.c index aba333452..e42263032 100644 --- a/fusee/fusee-secondary/src/nxfs.c +++ b/fusee/fusee-secondary/src/nxfs.c @@ -180,6 +180,36 @@ static void emummc_partition_finalize(device_partition_t *devpart) { } } +static int emummc_partition_read(device_partition_t *devpart, void *dst, uint64_t sector, uint64_t num_sectors) { + if (devpart->emu_use_file) { + /* Read partition data using our backing file. */ + int rc = 0; + FILE *emummc_file = fopen(devpart->emu_file_path, "rb"); + fseek(emummc_file, sector * devpart->sector_size, SEEK_CUR); + rc = (fread(dst, devpart->sector_size, num_sectors, emummc_file) > 0) ? 0 : -1; + fclose(emummc_file); + return rc; + } else { + /* Read partition data directly from the SD card device. */ + return sdmmc_device_read(&g_sd_device, (uint32_t)(devpart->start_sector + sector), (uint32_t)num_sectors, dst) ? 0 : EIO; + } +} + +static int emummc_partition_write(device_partition_t *devpart, const void *src, uint64_t sector, uint64_t num_sectors) { + if (devpart->emu_use_file) { + /* Write partition data using our backing file. */ + int rc = 0; + FILE *emummc_file = fopen(devpart->emu_file_path, "wb"); + fseek(emummc_file, sector * devpart->sector_size, SEEK_CUR); + rc = (fwrite(src, devpart->sector_size, num_sectors, emummc_file) > 0) ? 0 : -1; + fclose(emummc_file); + return rc; + } else { + /* Write partition data directly to the SD card device. */ + return sdmmc_device_write(&g_sd_device, (uint32_t)(devpart->start_sector + sector), (uint32_t)num_sectors, (void *)src) ? 0 : EIO; + } +} + 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_b = 5; @@ -232,8 +262,8 @@ static const device_partition_t g_emummc_devpart_template = { .sector_size = 512, .initializer = emummc_partition_initialize, .finalizer = emummc_partition_finalize, - .reader = NULL, - .writer = NULL, + .reader = emummc_partition_read, + .writer = emummc_partition_write, }; static int nxfs_mount_partition_gpt_callback(const efi_entry_t *entry, void *param, size_t entry_offset, FILE *disk) { @@ -517,14 +547,101 @@ int nxfs_mount_emmc() { return rc; } -int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_limit) { +int nxfs_mount_emummc_partition(uint64_t emummc_start_sector) { + device_partition_t model; + int rc; + FILE *rawnand; + + /* Setup an emulation template for boot0. */ + model = g_emummc_devpart_template; + model.start_sector = emummc_start_sector; + model.num_sectors = 0x184000 / model.sector_size; + model.emu_use_file = false; + + /* Mount emulated boot0 device. */ + rc = emudev_mount_device("boot0", &model, NULL); + + /* Failed to mount boot0 device. */ + if (rc == -1) { + return -1; + } + + /* Register emulated boot0 device. */ + rc = emudev_register_device("boot0"); + + /* Failed to register boot0 device. */ + if (rc == -1) { + return -1; + } + + /* Setup an emulation template for boot1. */ + model = g_emummc_devpart_template; + model.start_sector = emummc_start_sector; + model.num_sectors = 0x80000 / model.sector_size; + model.emu_use_file = false; + + /* Mount emulated boot1 device. */ + rc = emudev_mount_device("boot1", &model, NULL); + + /* Failed to mount boot1. */ + if (rc == -1) { + return -1; + } + + /* Don't register emulated boot1 for now. */ + + /* Setup a template for raw NAND. */ + model = g_emummc_devpart_template; + model.start_sector = emummc_start_sector; + model.num_sectors = (256ull << 30) / model.sector_size; + model.emu_use_file = false; + + /* Mount emulated raw NAND device. */ + rc = emudev_mount_device("rawnand", &model, NULL); + + /* Failed to mount raw NAND. */ + if (rc == -1) { + return -1; + } + + /* Register emulated raw NAND device. */ + rc = emudev_register_device("rawnand"); + + /* Failed to register raw NAND device. */ + if (rc == -1) { + return -1; + } + + /* Open emulated raw NAND device. */ + rawnand = fopen("rawnand:/", "rb"); + + /* Failed to open emulated raw NAND device. */ + if (rawnand == NULL) { + return -1; + } + + /* Iterate the GPT and mount each emulated raw NAND partition. */ + rc = gpt_iterate_through_emu_entries(rawnand, model.sector_size, nxfs_mount_emu_partition_gpt_callback, &model, NULL, false, 0, 0); + + /* Close emulated raw NAND device. */ + fclose(rawnand); + + /* All emulated devices are ready. */ + if (rc == 0) { + g_emudev_ready = true; + } + + return rc; +} + +int nxfs_mount_emummc_file(const char *emummc_path, int num_parts, uint64_t part_limit) { device_partition_t model; int rc; FILE *rawnand; bool is_exfat; - char emunand_boot0_path[0x300 + 1] = {0}; - char emunand_boot1_path[0x300 + 1] = {0}; - char emunand_rawnand_path[0x300 + 1] = {0}; + char emummc_boot0_path[0x300 + 1] = {0}; + char emummc_boot1_path[0x300 + 1] = {0}; + char emummc_rawnand_path[0x300 + 1] = {0}; /* Check if the SD card is EXFAT formatted. */ rc = fsdev_is_exfat("sdmc"); @@ -538,7 +655,7 @@ int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_l is_exfat = (rc == 1); /* We want a folder with the archive bit set. */ - rc = fsdev_get_attr(emunand_path); + rc = fsdev_get_attr(emummc_path); /* Failed to get file DOS attributes. */ if (rc == -1) { @@ -553,7 +670,7 @@ int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_l /* Check if the archive bit is not set. */ if (!(rc & AM_ARC)) { /* Try to set the archive bit. */ - rc = fsdev_set_attr(emunand_path, AM_ARC, AM_ARC); + rc = fsdev_set_attr(emummc_path, AM_ARC, AM_ARC); /* Failed to set file DOS attributes. */ if (rc == -1) { @@ -565,12 +682,13 @@ int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_l model = g_emummc_devpart_template; model.start_sector = 0; model.num_sectors = 0x184000 / model.sector_size; + model.emu_use_file = true; /* Prepare boot0 file path. */ - snprintf(emunand_boot0_path, sizeof(emunand_boot0_path) - 1, "sdmc:/%s/%s", emunand_path, "boot0"); + snprintf(emummc_boot0_path, sizeof(emummc_boot0_path) - 1, "sdmc:/%s/%s", emummc_path, "boot0"); /* Mount emulated boot0 device. */ - rc = emudev_mount_device("boot0", &model, emunand_boot0_path); + rc = emudev_mount_device("boot0", &model, emummc_boot0_path); /* Failed to mount boot0 device. */ if (rc == -1) { @@ -589,12 +707,13 @@ int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_l model = g_emummc_devpart_template; model.start_sector = 0; model.num_sectors = 0x80000 / model.sector_size; + model.emu_use_file = true; /* Prepare boot1 file path. */ - snprintf(emunand_boot1_path, sizeof(emunand_boot1_path) - 1, "sdmc:/%s/%s", emunand_path, "boot1"); + snprintf(emummc_boot1_path, sizeof(emummc_boot1_path) - 1, "sdmc:/%s/%s", emummc_path, "boot1"); /* Mount emulated boot1 device. */ - rc = emudev_mount_device("boot1", &model, emunand_boot1_path); + rc = emudev_mount_device("boot1", &model, emummc_boot1_path); /* Failed to mount boot1. */ if (rc == -1) { @@ -607,15 +726,16 @@ int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_l model = g_emummc_devpart_template; model.start_sector = 0; model.num_sectors = (256ull << 30) / model.sector_size; + model.emu_use_file = true; /* Prepare single raw NAND file path. */ - snprintf(emunand_rawnand_path, sizeof(emunand_rawnand_path) - 1, "sdmc:/%s/%02d", emunand_path, 0); + snprintf(emummc_rawnand_path, sizeof(emummc_rawnand_path) - 1, "sdmc:/%s/%02d", emummc_path, 0); /* Mount emulated raw NAND device from single or multiple parts. */ if (!is_exfat) { - rc = emudev_mount_device_multipart("rawnand", &model, emunand_path, num_parts, part_limit); + rc = emudev_mount_device_multipart("rawnand", &model, emummc_path, num_parts, part_limit); } else { - rc = emudev_mount_device("rawnand", &model, emunand_rawnand_path); + rc = emudev_mount_device("rawnand", &model, emummc_rawnand_path); } /* Failed to mount raw NAND. */ @@ -641,9 +761,9 @@ int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_l /* Iterate the GPT and mount each emulated raw NAND partition. */ if (!is_exfat) { - rc = gpt_iterate_through_emu_entries(rawnand, model.sector_size, nxfs_mount_emu_partition_gpt_callback, &model, emunand_path, true, num_parts, part_limit); + rc = gpt_iterate_through_emu_entries(rawnand, model.sector_size, nxfs_mount_emu_partition_gpt_callback, &model, emummc_path, true, num_parts, part_limit); } else { - rc = gpt_iterate_through_emu_entries(rawnand, model.sector_size, nxfs_mount_emu_partition_gpt_callback, &model, emunand_rawnand_path, false, num_parts, part_limit); + rc = gpt_iterate_through_emu_entries(rawnand, model.sector_size, nxfs_mount_emu_partition_gpt_callback, &model, emummc_rawnand_path, false, 0, 0); } /* Close emulated raw NAND device. */ @@ -681,7 +801,7 @@ int nxfs_unmount_emmc() { return rc; } -int nxfs_unmount_emu_emmc() { +int nxfs_unmount_emummc() { int rc = 0; /* Unmount all emulated devices. */ @@ -708,5 +828,5 @@ int nxfs_init() { } int nxfs_end() { - return ((nxfs_unmount_sd() || nxfs_unmount_emmc() || nxfs_unmount_emu_emmc()) ? -1 : 0); + return ((nxfs_unmount_sd() || nxfs_unmount_emmc() || nxfs_unmount_emummc()) ? -1 : 0); } diff --git a/fusee/fusee-secondary/src/nxfs.h b/fusee/fusee-secondary/src/nxfs.h index 46eb4e364..ca3cba697 100644 --- a/fusee/fusee-secondary/src/nxfs.h +++ b/fusee/fusee-secondary/src/nxfs.h @@ -26,9 +26,10 @@ int nxfs_end(); int nxfs_mount_sd(); int nxfs_mount_emmc(); -int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_limit); +int nxfs_mount_emummc_partition(uint64_t emummc_start_sector); +int nxfs_mount_emummc_file(const char *emummc_path, int num_parts, uint64_t part_limit); int nxfs_unmount_sd(); int nxfs_unmount_emmc(); -int nxfs_unmount_emu_emmc(); +int nxfs_unmount_emummc(); #endif