emummc: Add boot entry emuMMC selection

Using the key `emupath` on a boot entry will load the selected emuMMC.
This can also be forced by using the correct boot cfg storage bit and writing the path at the emummc path offset. Check readme for these.

This can only be used if the emuMMC was created via Nyx. because of the raw_based and file_based files that have emuMMC info.
(emupath=emuMMC/RAW1, emupath=emuMMC/SD00, etc)
This commit is contained in:
CTCaer
2020-04-27 09:30:53 +03:00
parent 3fa537e54a
commit 4160037c81
6 changed files with 117 additions and 20 deletions

View File

@@ -280,7 +280,7 @@ bool is_ipl_updated(void *buf, char *path, bool force)
f_open(&fp, path, FA_WRITE | FA_CREATE_ALWAYS);
f_write(&fp, (u8 *)reloc->start, reloc->end - reloc->start, NULL);
// Write needed tag in case injected ipl uses old versioning.
f_write(&fp, "ICTC49", 6, NULL);
@@ -326,7 +326,7 @@ int launch_payload(char *path, bool update)
if (f_read(&fp, buf, size, NULL))
{
f_close(&fp);
goto out;
}
@@ -476,6 +476,7 @@ void ini_list_launcher()
{
u8 max_entries = 61;
char *payload_path = NULL;
char *emummc_path = NULL;
ini_sec_t *cfg_sec = NULL;
LIST_INIT(ini_list_sections);
@@ -539,6 +540,20 @@ void ini_list_launcher()
payload_path = ini_check_payload_section(cfg_sec);
if (cfg_sec)
{
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link)
{
if (!strcmp("emummc_force_disable", kv->key))
h_cfg.emummc_force_disable = atoi(kv->val);
else if (!strcmp("emupath", kv->key))
emummc_path = kv->val;
}
}
if (emummc_path)
emummc_set_path(emummc_path);
if (cfg_sec && !payload_path)
check_sept(cfg_sec);
@@ -569,6 +584,13 @@ void ini_list_launcher()
else if (!hos_launch(cfg_sec))
{
EPRINTF("Failed to launch firmware.");
if (emummc_path)
{
sd_mount();
emummc_load_cfg();
}
btn_wait();
}
@@ -581,6 +603,7 @@ void launch_firmware()
{
u8 max_entries = 61;
char *payload_path = NULL;
char *emummc_path = NULL;
ini_sec_t *cfg_sec = NULL;
LIST_INIT(ini_sections);
@@ -663,9 +686,14 @@ void launch_firmware()
{
if (!strcmp("emummc_force_disable", kv->key))
h_cfg.emummc_force_disable = atoi(kv->val);
if (!strcmp("emupath", kv->key))
emummc_path = kv->val;
}
}
if (emummc_path)
emummc_set_path(emummc_path);
if (cfg_sec && !payload_path)
check_sept(cfg_sec);
@@ -699,7 +727,14 @@ void launch_firmware()
free(payload_path);
}
else if (!hos_launch(cfg_sec))
{
EPRINTF("Failed to launch firmware.");
if (emummc_path)
{
sd_mount();
emummc_load_cfg();
}
}
out:
sd_unmount();
@@ -771,7 +806,7 @@ void nyx_load_run()
(*nyx_ptr)();
}
static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char **bootlogoCustomEntry)
static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char **bootlogoCustomEntry, char **emummc_path)
{
ini_sec_t *cfg_sec = NULL;
@@ -788,10 +823,13 @@ static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char **bootlogoCustomE
*bootlogoCustomEntry = kv->val;
if (!strcmp("emummc_force_disable", kv->key))
h_cfg.emummc_force_disable = atoi(kv->val);
if (!strcmp("emupath", kv->key))
*emummc_path = kv->val;
}
if (!cfg_sec)
{
*bootlogoCustomEntry = NULL;
*emummc_path = NULL;
h_cfg.emummc_force_disable = false;
}
@@ -812,6 +850,7 @@ static void _auto_launch_firmware()
u8 *BOOTLOGO = NULL;
char *payload_path = NULL;
char *emummc_path = NULL;
u32 btn = 0;
bool boot_from_id = (b_cfg.boot_cfg & BOOT_CFG_FROM_ID) && (b_cfg.boot_cfg & BOOT_CFG_AUTOBOOT_EN);
if (boot_from_id)
@@ -902,7 +941,7 @@ static void _auto_launch_firmware()
}
if (boot_from_id)
cfg_sec = get_ini_sec_from_id(ini_sec, &bootlogoCustomEntry);
cfg_sec = get_ini_sec_from_id(ini_sec, &bootlogoCustomEntry, &emummc_path);
else if (h_cfg.autoboot == boot_entry_id && configEntry)
{
cfg_sec = ini_sec;
@@ -910,8 +949,10 @@ static void _auto_launch_firmware()
{
if (!strcmp("logopath", kv->key))
bootlogoCustomEntry = kv->val;
if (!strcmp("emummc_force_disable", kv->key))
else if (!strcmp("emummc_force_disable", kv->key))
h_cfg.emummc_force_disable = atoi(kv->val);
else if (!strcmp("emupath", kv->key))
emummc_path = kv->val;
}
}
if (cfg_sec)
@@ -942,7 +983,7 @@ static void _auto_launch_firmware()
continue;
if (boot_from_id)
cfg_sec = get_ini_sec_from_id(ini_sec_list, &bootlogoCustomEntry);
cfg_sec = get_ini_sec_from_id(ini_sec_list, &bootlogoCustomEntry, &emummc_path);
else if (h_cfg.autoboot == boot_entry_id)
{
h_cfg.emummc_force_disable = false;
@@ -951,8 +992,10 @@ static void _auto_launch_firmware()
{
if (!strcmp("logopath", kv->key))
bootlogoCustomEntry = kv->val;
if (!strcmp("emummc_force_disable", kv->key))
else if (!strcmp("emummc_force_disable", kv->key))
h_cfg.emummc_force_disable = atoi(kv->val);
else if (!strcmp("emupath", kv->key))
emummc_path = kv->val;
}
}
if (cfg_sec)
@@ -1064,9 +1107,19 @@ skip_list:
}
else
{
if (b_cfg.boot_cfg & BOOT_CFG_TO_EMUMMC)
emummc_set_path(b_cfg.emummc_path);
else if (emummc_path)
emummc_set_path(emummc_path);
check_sept(cfg_sec);
hos_launch(cfg_sec);
if (emummc_path || b_cfg.boot_cfg & BOOT_CFG_TO_EMUMMC)
{
sd_mount();
emummc_load_cfg();
}
EPRINTF("\nFailed to launch HOS!");
gfx_printf("\nPress any key...\n");
msleep(500);
@@ -1077,9 +1130,9 @@ out:
gfx_con.mute = false;
// Clear boot reasons from binary.
if (b_cfg.boot_cfg & BOOT_CFG_FROM_ID)
if (b_cfg.boot_cfg & (BOOT_CFG_FROM_ID | BOOT_CFG_TO_EMUMMC))
memset(b_cfg.xt_str, 0, sizeof(b_cfg.xt_str));
b_cfg.boot_cfg &= ~(BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_FROM_LAUNCH | BOOT_CFG_FROM_ID);
b_cfg.boot_cfg &= ~(BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_FROM_LAUNCH | BOOT_CFG_FROM_ID | BOOT_CFG_TO_EMUMMC);
h_cfg.emummc_force_disable = false;
nyx_load_run();
@@ -1254,7 +1307,7 @@ static void _check_low_battery()
free(battery_icon);
free(charging_icon);
free(no_charging_icon);
// Re enable Low Battery Monitor shutdown.
max77620_low_battery_monitor_config(true);
}

View File

@@ -38,7 +38,6 @@ extern void sd_unmount();
void emummc_load_cfg()
{
sd_mount();
emu_cfg.enabled = 0;
emu_cfg.path = NULL;
emu_cfg.nintendo_path = NULL;
@@ -47,7 +46,8 @@ void emummc_load_cfg()
emu_cfg.file_based_part_size = 0;
emu_cfg.active_part = 0;
emu_cfg.fs_ver = 0;
emu_cfg.emummc_file_based_path = (char *)malloc(0x80);
if (!emu_cfg.emummc_file_based_path)
emu_cfg.emummc_file_based_path = (char *)malloc(0x80);
LIST_INIT(ini_sections);
if (ini_parse(&ini_sections, "emuMMC/emummc.ini", false))
@@ -78,6 +78,43 @@ void emummc_load_cfg()
}
}
void emummc_set_path(char *path)
{
FIL fp;
bool found = false;
strcpy(emu_cfg.emummc_file_based_path, path);
strcat(emu_cfg.emummc_file_based_path, "/raw_based");
if (!f_open(&fp, emu_cfg.emummc_file_based_path, FA_READ))
{
if (!f_read(&fp, &emu_cfg.sector, 4, NULL))
if (emu_cfg.sector)
found = true;
}
else
{
strcpy(emu_cfg.emummc_file_based_path, path);
strcat(emu_cfg.emummc_file_based_path, "/file_based");
if (!f_stat(emu_cfg.emummc_file_based_path, NULL))
{
emu_cfg.sector = 0;
emu_cfg.path = path;
found = true;
}
}
if (found)
{
emu_cfg.enabled = 1;
emu_cfg.id = 0;
strcpy(emu_cfg.nintendo_path, path);
strcpy(emu_cfg.nintendo_path, "/Nintendo");
}
}
static int emummc_raw_get_part_off(int part_idx)
{
switch (part_idx)

View File

@@ -50,6 +50,7 @@ typedef struct _emummc_cfg_t
emummc_cfg_t emu_cfg;
void emummc_load_cfg();
void emummc_set_path(char *path);
int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
int emummc_storage_end(sdmmc_storage_t *storage);
int emummc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);

View File

@@ -55,6 +55,7 @@ typedef int bool;
#define BOOT_CFG_AUTOBOOT_EN (1 << 0)
#define BOOT_CFG_FROM_LAUNCH (1 << 1)
#define BOOT_CFG_FROM_ID (1 << 2)
#define BOOT_CFG_TO_EMUMMC (1 << 3)
#define BOOT_CFG_SEPT_RUN (1 << 7)
#define EXTRA_CFG_KEYS (1 << 0)
@@ -75,6 +76,7 @@ typedef struct __attribute__((__packed__)) _boot_cfg_t
struct
{
char id[8];
char emummc_path[0x78];
};
u8 xt_str[0x80];
};