diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 7828268a6..0b200abe9 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -1,7 +1,13 @@ #include +#include +#include +#include "sdmmc.h" +#include "raw_mmc_dev.h" #include "utils.h" #include "nxboot.h" #include "key_derivation.h" +#include "gpt.h" +#include "package1.h" #include "package2.h" #include "loader.h" #include "splash_screen.h" @@ -43,10 +49,64 @@ void nxboot_configure_exosphere(void) { *(MAILBOX_EXOSPHERE_CONFIGURATION) = exo_cfg; } +static struct mmc nand_mmc; /* TODO: Remove, move it elsewhere and actually initalize the controller!! */ + +static int init_rawnand_and_boot0_devices(void) { + if (rawmmcdev_mount_unencrypted_device("rawnand", &nand_mmc, SDMMC_PARTITION_USER, 0, 32ull<<30) == -1) { + return -1; + } + if (rawmmcdev_mount_unencrypted_device("boot0", &nand_mmc, SDMMC_PARTITION_BOOT0, 0, 0x184000) == -1) { + return -1; + } + + return 0; +} + +static bool g_bcpkg2_initialized = false; +static int bcpkg2_finder_callback(const efi_entry_t *entry, size_t entry_offset, FILE *disk) { + /* TODO: what about backup partitions? */ + static const uint16_t part_name[] = u"BCPKG2-1-Normal-Main"; + if (memcmp(entry->name, part_name, sizeof(part_name)) == 0) { + uint64_t part_offset = 512 * entry->first_lba; + uint64_t part_size = 512 * (entry->last_lba - entry->first_lba); + + int rc = rawmmcdev_mount_unencrypted_device("bcpkg2", &nand_mmc, SDMMC_PARTITION_USER, part_offset, part_size); + + g_bcpkg2_initialized = rc == 0; + return rc; + } + + return 0; +} + +/* Find BCPKG2-1-Normal-Main using the GPT, then register it. */ +static int init_bcpkg2_device(void) { + FILE *rawnand = fopen("rawnand:/", "rb"); + int rc; + if (rawnand == NULL) { + return -1; + } + + rc = gpt_iterate_through_entries(rawnand, bcpkg2_finder_callback); + fclose(rawnand); + + if (rc == 0 && !g_bcpkg2_initialized) { + errno = ENOENT; + return -1; + } + + return rc; +} + /* This is the main function responsible for booting Horizon. */ void nxboot_main(void) { loader_ctx_t *loader_ctx = get_loader_ctx(); + /* TODO: this is not always necessary */ + if (init_rawnand_and_boot0_devices()) { + printf("Error: Failed to mount rawnand and/or boot0: %s!\n", strerror(errno)); + generic_panic(); + } /* TODO: Validate that we're capable of booting. */ /* TODO: Initialize Boot Reason. */ @@ -59,6 +119,15 @@ void nxboot_main(void) { /* Derive keydata. */ derive_nx_keydata(MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware); + if (loader_ctx->package2_loadfile.load_address == 0) { + if (init_bcpkg2_device() == -1) { + printf("Error: Failed to mount BCPKG2-1-Normal-Main: %s!\n", strerror(errno)); + generic_panic(); + } + + /* TODO: read package2 somewhere. */ + } + /* Patch package2, adding thermosphere + custom KIPs. */ package2_rebuild_and_copy((void *)loader_ctx->package2_loadfile.load_address); @@ -82,5 +151,7 @@ void nxboot_main(void) { /* Display splash screen. */ display_splash_screen_bmp(loader_ctx->custom_splash_path); + rawmmcdev_unmount_all(); + /* TODO: Halt ourselves. */ }