diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 3a33463ab..29cf5237d 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -213,66 +213,45 @@ static bool nxboot_configure_emunand() { } if (emunand_cfg.enabled) { - bool do_nand_backup = false; 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_base_path[0x300 + 1] = {0}; - 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"); - snprintf(emunand_rawnand_base_path, sizeof(emunand_rawnand_base_path) - 1, "sdmc:/%s/%s", emunand_cfg.path, "rawnand"); + 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"); } - /* Check if full rawnand image file is present. */ - if (!is_valid_file(emunand_rawnand_base_path)) { - char emunand_rawnand_path[0x300 + 4 + 1] = {0}; - - /* Search for rawnand part files instead. */ - for (int i = 0; i < 64; 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 (i == 0) { - /* The size of the first part file should tell us the part limit. */ - part_limit = get_file_size(emunand_rawnand_path); - } - num_parts++; + /* 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); } - } - - /* Check if at least the first part of the rawnand image file is present. */ - /* TODO: This fully trusts the user to provide properly split files. Do better checks? */ - if ((num_parts == 0) || (part_limit == 0)) { - fatal_error("[NXBOOT] Failed to find EmuNAND rawnand image files!\n"); + num_parts++; } } - if (do_nand_backup) { - /* Mount real NAND. */ - if (nxfs_mount_emmc() < 0) { - fatal_error("[NXBOOT] Failed to mount eMMC!\n"); - } - - /* TODO: Read real NAND and create a backup image. */ - - /* Unmount real NAND. */ - if (nxfs_unmount_emmc() < 0) { - fatal_error("[NXBOOT] Failed to unmount eMMC!\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"); } /* Mount emulated NAND. */ - if (nxfs_mount_emu_emmc(emunand_boot0_path, emunand_boot1_path, emunand_rawnand_base_path, num_parts, part_limit) < 0) { + if (nxfs_mount_emu_emmc(emunand_cfg.path, num_parts, part_limit) < 0) { fatal_error("[NXBOOT] Failed to mount emulated eMMC!\n"); } } diff --git a/fusee/fusee-secondary/src/nxfs.c b/fusee/fusee-secondary/src/nxfs.c index 129210901..aba333452 100644 --- a/fusee/fusee-secondary/src/nxfs.c +++ b/fusee/fusee-secondary/src/nxfs.c @@ -517,11 +517,14 @@ int nxfs_mount_emmc() { return rc; } -int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot1_path, const char *emunand_rawnand_base_path, int num_parts, uint64_t part_limit) { +int nxfs_mount_emu_emmc(const char *emunand_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}; /* Check if the SD card is EXFAT formatted. */ rc = fsdev_is_exfat("sdmc"); @@ -534,14 +537,42 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot /* Set EXFAT status. */ is_exfat = (rc == 1); + /* We want a folder with the archive bit set. */ + rc = fsdev_get_attr(emunand_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_path, AM_ARC, AM_ARC); + + /* Failed to set file DOS attributes. */ + if (rc == -1) { + return -1; + } + } + /* Setup an emulation template for boot0. */ model = g_emummc_devpart_template; model.start_sector = 0; model.num_sectors = 0x184000 / model.sector_size; + /* Prepare boot0 file path. */ + snprintf(emunand_boot0_path, sizeof(emunand_boot0_path) - 1, "sdmc:/%s/%s", emunand_path, "boot0"); + /* Mount emulated boot0 device. */ rc = emudev_mount_device("boot0", &model, emunand_boot0_path); + /* Failed to mount boot0 device. */ if (rc == -1) { return -1; } @@ -549,6 +580,7 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot /* Register emulated boot0 device. */ rc = emudev_register_device("boot0"); + /* Failed to register boot0 device. */ if (rc == -1) { return -1; } @@ -558,9 +590,13 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot model.start_sector = 0; model.num_sectors = 0x80000 / model.sector_size; + /* Prepare boot1 file path. */ + snprintf(emunand_boot1_path, sizeof(emunand_boot1_path) - 1, "sdmc:/%s/%s", emunand_path, "boot1"); + /* Mount emulated boot1 device. */ rc = emudev_mount_device("boot1", &model, emunand_boot1_path); + /* Failed to mount boot1. */ if (rc == -1) { return -1; } @@ -572,48 +608,25 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot model.start_sector = 0; model.num_sectors = (256ull << 30) / model.sector_size; + /* Prepare single raw NAND file path. */ + snprintf(emunand_rawnand_path, sizeof(emunand_rawnand_path) - 1, "sdmc:/%s/%02d", emunand_path, 0); + + /* Mount emulated raw NAND device from single or multiple parts. */ 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. */ - rc = emudev_mount_device_multipart("rawnand", &model, emunand_rawnand_base_path, num_parts, part_limit); - - if (rc == -1) { - return -1; - } + rc = emudev_mount_device_multipart("rawnand", &model, emunand_path, num_parts, part_limit); } else { - /* Mount emulated raw NAND device. */ - rc = emudev_mount_device("rawnand", &model, emunand_rawnand_base_path); - - if (rc == -1) { - return -1; - } + rc = emudev_mount_device("rawnand", &model, emunand_rawnand_path); + } + + /* 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; } @@ -621,13 +634,18 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot /* 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, emunand_rawnand_base_path, !is_exfat, num_parts, part_limit); - + 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); + } 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); + } + /* Close emulated raw NAND device. */ fclose(rawnand); diff --git a/fusee/fusee-secondary/src/nxfs.h b/fusee/fusee-secondary/src/nxfs.h index 5e1ed8546..46eb4e364 100644 --- a/fusee/fusee-secondary/src/nxfs.h +++ b/fusee/fusee-secondary/src/nxfs.h @@ -26,7 +26,7 @@ int nxfs_end(); int nxfs_mount_sd(); int nxfs_mount_emmc(); -int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot1_path, const char *emunand_rawnand_base_path, int num_parts, uint64_t part_limit); +int nxfs_mount_emu_emmc(const char *emunand_path, int num_parts, uint64_t part_limit); int nxfs_unmount_sd(); int nxfs_unmount_emmc(); int nxfs_unmount_emu_emmc();