mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
fusee: update and simplify emunand image path handling
This commit is contained in:
parent
837b30d075
commit
00e22c7fd0
3 changed files with 75 additions and 78 deletions
|
@ -213,66 +213,45 @@ static bool nxboot_configure_emunand() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emunand_cfg.enabled) {
|
if (emunand_cfg.enabled) {
|
||||||
bool do_nand_backup = false;
|
|
||||||
int num_parts = 0;
|
int num_parts = 0;
|
||||||
uint64_t part_limit = 0;
|
uint64_t part_limit = 0;
|
||||||
char emunand_boot0_path[0x300 + 1] = {0};
|
char emunand_boot0_path[0x300 + 1] = {0};
|
||||||
char emunand_boot1_path[0x300 + 1] = {0};
|
char emunand_boot1_path[0x300 + 1] = {0};
|
||||||
char emunand_rawnand_base_path[0x300 + 1] = {0};
|
char emunand_rawnand_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");
|
|
||||||
|
|
||||||
/* Check if the supplied path is valid. */
|
/* Check if the supplied path is valid. */
|
||||||
if (!is_valid_folder(emunand_cfg.path)) {
|
if (!is_valid_folder(emunand_cfg.path)) {
|
||||||
fatal_error("[NXBOOT] Failed to find EmuNAND folder!\n");
|
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. */
|
/* Check if boot0 and boot1 image files are present. */
|
||||||
if (!is_valid_file(emunand_boot0_path) || !is_valid_file(emunand_boot1_path)) {
|
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");
|
fatal_error("[NXBOOT] Failed to find EmuNAND boot0/boot1 image files!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if full rawnand image file is present. */
|
/* Find raw image files (single or multi part). */
|
||||||
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++) {
|
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, "sdmc:/%s/%02d", emunand_cfg.path, i);
|
||||||
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 file should tell us the part limit. */
|
||||||
part_limit = get_file_size(emunand_rawnand_path);
|
part_limit = get_file_size(emunand_rawnand_path);
|
||||||
}
|
}
|
||||||
num_parts++;
|
num_parts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if at least the first part of the rawnand image file is present. */
|
/* Check if at least one raw 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)) {
|
if ((num_parts == 0) || (part_limit == 0)) {
|
||||||
fatal_error("[NXBOOT] Failed to find EmuNAND rawnand image files!\n");
|
fatal_error("[NXBOOT] Failed to find EmuNAND raw image files!\n");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mount emulated NAND. */
|
/* 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");
|
fatal_error("[NXBOOT] Failed to mount emulated eMMC!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -517,11 +517,14 @@ int nxfs_mount_emmc() {
|
||||||
return rc;
|
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;
|
device_partition_t model;
|
||||||
int rc;
|
int rc;
|
||||||
FILE *rawnand;
|
FILE *rawnand;
|
||||||
bool is_exfat;
|
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. */
|
/* Check if the SD card is EXFAT formatted. */
|
||||||
rc = fsdev_is_exfat("sdmc");
|
rc = fsdev_is_exfat("sdmc");
|
||||||
|
@ -534,47 +537,8 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot
|
||||||
/* Set EXFAT status. */
|
/* Set EXFAT status. */
|
||||||
is_exfat = (rc == 1);
|
is_exfat = (rc == 1);
|
||||||
|
|
||||||
/* Setup an emulation template for boot0. */
|
/* We want a folder with the archive bit set. */
|
||||||
model = g_emummc_devpart_template;
|
rc = fsdev_get_attr(emunand_path);
|
||||||
model.start_sector = 0;
|
|
||||||
model.num_sectors = 0x184000 / model.sector_size;
|
|
||||||
|
|
||||||
/* Mount emulated boot0 device. */
|
|
||||||
rc = emudev_mount_device("boot0", &model, emunand_boot0_path);
|
|
||||||
|
|
||||||
if (rc == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Register emulated boot0 device. */
|
|
||||||
rc = emudev_register_device("boot0");
|
|
||||||
|
|
||||||
if (rc == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup an emulation template for boot1. */
|
|
||||||
model = g_emummc_devpart_template;
|
|
||||||
model.start_sector = 0;
|
|
||||||
model.num_sectors = 0x80000 / model.sector_size;
|
|
||||||
|
|
||||||
/* Mount emulated boot1 device. */
|
|
||||||
rc = emudev_mount_device("boot1", &model, emunand_boot1_path);
|
|
||||||
|
|
||||||
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 = 0;
|
|
||||||
model.num_sectors = (256ull << 30) / model.sector_size;
|
|
||||||
|
|
||||||
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. */
|
/* Failed to get file DOS attributes. */
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
|
@ -589,7 +553,7 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot
|
||||||
/* Check if the archive bit is not set. */
|
/* Check if the archive bit is not set. */
|
||||||
if (!(rc & AM_ARC)) {
|
if (!(rc & AM_ARC)) {
|
||||||
/* Try to set the archive bit. */
|
/* Try to set the archive bit. */
|
||||||
rc = fsdev_set_attr(emunand_rawnand_base_path, AM_ARC, AM_ARC);
|
rc = fsdev_set_attr(emunand_path, AM_ARC, AM_ARC);
|
||||||
|
|
||||||
/* Failed to set file DOS attributes. */
|
/* Failed to set file DOS attributes. */
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
|
@ -597,23 +561,72 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mount emulated raw NAND device from multiple parts. */
|
/* Setup an emulation template for boot0. */
|
||||||
rc = emudev_mount_device_multipart("rawnand", &model, emunand_rawnand_base_path, num_parts, part_limit);
|
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) {
|
if (rc == -1) {
|
||||||
return -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 = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't register emulated boot1 for now. */
|
||||||
|
|
||||||
|
/* Setup a template for raw NAND. */
|
||||||
|
model = g_emummc_devpart_template;
|
||||||
|
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) {
|
||||||
|
rc = emudev_mount_device_multipart("rawnand", &model, emunand_path, num_parts, part_limit);
|
||||||
} else {
|
} else {
|
||||||
/* Mount emulated raw NAND device. */
|
rc = emudev_mount_device("rawnand", &model, emunand_rawnand_path);
|
||||||
rc = emudev_mount_device("rawnand", &model, emunand_rawnand_base_path);
|
}
|
||||||
|
|
||||||
|
/* Failed to mount raw NAND. */
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Register emulated raw NAND device. */
|
/* Register emulated raw NAND device. */
|
||||||
rc = emudev_register_device("rawnand");
|
rc = emudev_register_device("rawnand");
|
||||||
|
|
||||||
|
/* Failed to register raw NAND device. */
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -621,12 +634,17 @@ int nxfs_mount_emu_emmc(const char *emunand_boot0_path, const char *emunand_boot
|
||||||
/* Open emulated raw NAND device. */
|
/* Open emulated raw NAND device. */
|
||||||
rawnand = fopen("rawnand:/", "rb");
|
rawnand = fopen("rawnand:/", "rb");
|
||||||
|
|
||||||
|
/* Failed to open emulated raw NAND device. */
|
||||||
if (rawnand == NULL) {
|
if (rawnand == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate the GPT and mount each emulated raw NAND partition. */
|
/* 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. */
|
/* Close emulated raw NAND device. */
|
||||||
fclose(rawnand);
|
fclose(rawnand);
|
||||||
|
|
|
@ -26,7 +26,7 @@ int nxfs_end();
|
||||||
|
|
||||||
int nxfs_mount_sd();
|
int nxfs_mount_sd();
|
||||||
int nxfs_mount_emmc();
|
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_sd();
|
||||||
int nxfs_unmount_emmc();
|
int nxfs_unmount_emmc();
|
||||||
int nxfs_unmount_emu_emmc();
|
int nxfs_unmount_emu_emmc();
|
||||||
|
|
Loading…
Reference in a new issue