mirror of
https://github.com/CTCaer/hekate
synced 2024-11-16 00:49:27 +00:00
sept: Add support for loading sept from fss0
If `fss0=` key is detected, sept will be loaded from fusee-secondary.bin instead of `sept/sept_*`. This will negate missing sept and failed to decrypt pkg2 errors, when booting HOS, for users that forget to update sept folder.
This commit is contained in:
parent
9b2d906648
commit
8584493c7f
8 changed files with 120 additions and 61 deletions
|
@ -30,6 +30,7 @@ Custom Nintendo Switch bootloader, firmware patcher, and more.
|
||||||
| bootloader/screenshots/ | Folder where Nyx screenshots are saved |
|
| bootloader/screenshots/ | Folder where Nyx screenshots are saved |
|
||||||
| bootloader/payloads/ | For payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. |
|
| bootloader/payloads/ | For payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. |
|
||||||
| bootloader/libtools/ | Future reserved |
|
| bootloader/libtools/ | Future reserved |
|
||||||
|
| sept | Sept folder. This must be always get updated via the Atmosphère release zip. Needed for tools and booting HOS on 7.0.0 and up. Unused for booting HOS if `fss0=` key is defined. |
|
||||||
|
|
||||||
**Note**: Sept files for booting 7.0.0 and up are expected at /sept folder at root of sd card.
|
**Note**: Sept files for booting 7.0.0 and up are expected at /sept folder at root of sd card.
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||||
| kernel={SD path} | Replaces the kernel binary |
|
| kernel={SD path} | Replaces the kernel binary |
|
||||||
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||||
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||||
| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. |
|
| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. kips, exosphere, warmboot and sept. |
|
||||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up |
|
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up |
|
||||||
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
||||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||||
|
|
|
@ -109,7 +109,7 @@ void dump_packages12()
|
||||||
gfx_printf("sept will run to get the keys.\nThen rerun this option.");
|
gfx_printf("sept will run to get the keys.\nThen rerun this option.");
|
||||||
btn_wait();
|
btn_wait();
|
||||||
|
|
||||||
if (!reboot_to_sept((u8 *)tsec_ctxt.fw, kb))
|
if (!reboot_to_sept((u8 *)tsec_ctxt.fw, kb, NULL))
|
||||||
{
|
{
|
||||||
gfx_printf("Failed to run sept\n");
|
gfx_printf("Failed to run sept\n");
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
|
@ -90,11 +90,12 @@ static void _update_r2p(const char *path)
|
||||||
free(r2p_path);
|
free(r2p_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_fss(launch_ctxt_t *ctxt, const char *path)
|
int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
|
||||||
{
|
{
|
||||||
FIL fp;
|
FIL fp;
|
||||||
|
|
||||||
bool stock = false;
|
bool stock = false;
|
||||||
|
int sept_used = 0;
|
||||||
|
|
||||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
|
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
|
||||||
{
|
{
|
||||||
|
@ -103,13 +104,14 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path)
|
||||||
stock = true;
|
stock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
|
if (!sept_ctxt && stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (f_open(&fp, path, FA_READ) != FR_OK)
|
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ctxt->atmosphere = true;
|
if (!sept_ctxt)
|
||||||
|
ctxt->atmosphere = true;
|
||||||
|
|
||||||
void *fss = malloc(f_size(&fp));
|
void *fss = malloc(f_size(&fp));
|
||||||
// Read header.
|
// Read header.
|
||||||
|
@ -135,29 +137,48 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Load content to launch context.
|
// Load content to launch context.
|
||||||
switch (curr_fss_cnt[i].type)
|
if (!sept_ctxt)
|
||||||
{
|
{
|
||||||
case CNT_TYPE_KIP:
|
switch (curr_fss_cnt[i].type)
|
||||||
if (stock)
|
{
|
||||||
|
case CNT_TYPE_KIP:
|
||||||
|
if (stock)
|
||||||
|
continue;
|
||||||
|
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||||
|
mkip1->kip1 = content;
|
||||||
|
list_append(&ctxt->kip1_list, &mkip1->link);
|
||||||
|
DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size);
|
||||||
|
break;
|
||||||
|
case CNT_TYPE_EXO:
|
||||||
|
ctxt->secmon_size = curr_fss_cnt[i].size;
|
||||||
|
ctxt->secmon = content;
|
||||||
|
break;
|
||||||
|
case CNT_TYPE_WBT:
|
||||||
|
ctxt->warmboot_size = curr_fss_cnt[i].size;
|
||||||
|
ctxt->warmboot = content;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
continue;
|
continue;
|
||||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
}
|
||||||
mkip1->kip1 = content;
|
}
|
||||||
list_append(&ctxt->kip1_list, &mkip1->link);
|
else
|
||||||
DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size);
|
{
|
||||||
break;
|
// Load content to launch context.
|
||||||
case CNT_TYPE_EXO:
|
switch (curr_fss_cnt[i].type)
|
||||||
ctxt->secmon_size = curr_fss_cnt[i].size;
|
{
|
||||||
ctxt->secmon = content;
|
case CNT_TYPE_SP1:
|
||||||
break;
|
memcpy(sept_ctxt->sept_primary, content, curr_fss_cnt[i].size);
|
||||||
case CNT_TYPE_WBT:
|
break;
|
||||||
ctxt->warmboot_size = curr_fss_cnt[i].size;
|
case CNT_TYPE_SP2:
|
||||||
ctxt->warmboot = content;
|
if (!memcmp(curr_fss_cnt[i].name, (sept_ctxt->kb < KB_FIRMWARE_VERSION_810) ? "septsecondary00" : "septsecondary01", 15))
|
||||||
break;
|
{
|
||||||
default:
|
memcpy(sept_ctxt->sept_secondary, content, curr_fss_cnt[i].size);
|
||||||
continue;
|
sept_used = 1;
|
||||||
// TODO: add more types?
|
}
|
||||||
// case CNT_TYPE_SP1:
|
break;
|
||||||
// case CNT_TYPE_SP2:
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f_lseek(&fp, curr_fss_cnt[i].offset);
|
f_lseek(&fp, curr_fss_cnt[i].offset);
|
||||||
|
@ -169,11 +190,22 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path)
|
||||||
|
|
||||||
_update_r2p(path);
|
_update_r2p(path);
|
||||||
|
|
||||||
return 1;
|
return (!sept_ctxt ? 1 : sept_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
free(fss);
|
free(fss);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int load_sept_from_ffs0(fss0_sept_t *sept_ctxt)
|
||||||
|
{
|
||||||
|
LIST_FOREACH_ENTRY(ini_kv_t, kv, &sept_ctxt->cfg_sec->kvs, link)
|
||||||
|
{
|
||||||
|
if (!strcmp("fss0", kv->key))
|
||||||
|
return parse_fss(NULL, kv->val, sept_ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,16 @@
|
||||||
|
|
||||||
#include "hos.h"
|
#include "hos.h"
|
||||||
|
|
||||||
int parse_fss(launch_ctxt_t *ctxt, const char *path);
|
typedef struct _fss0_sept_t
|
||||||
|
{
|
||||||
|
u32 kb;
|
||||||
|
ini_sec_t *cfg_sec;
|
||||||
|
void *sept_primary;
|
||||||
|
void *sept_secondary;
|
||||||
|
|
||||||
|
} fss0_sept_t;
|
||||||
|
|
||||||
|
int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt);
|
||||||
|
int load_sept_from_ffs0(fss0_sept_t *sept_ctxt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -213,7 +213,7 @@ static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value)
|
||||||
|
|
||||||
static int _config_fss(launch_ctxt_t *ctxt, const char *value)
|
static int _config_fss(launch_ctxt_t *ctxt, const char *value)
|
||||||
{
|
{
|
||||||
return parse_fss(ctxt, value);
|
return parse_fss(ctxt, value, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _cfg_handler_t
|
typedef struct _cfg_handler_t
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "hos.h"
|
#include "hos.h"
|
||||||
|
#include "fss.h"
|
||||||
#include "sept.h"
|
#include "sept.h"
|
||||||
#include "../config/config.h"
|
#include "../config/config.h"
|
||||||
#include "../gfx/di.h"
|
#include "../gfx/di.h"
|
||||||
|
@ -73,7 +74,7 @@ extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
|
||||||
extern sdmmc_t sd_sdmmc;
|
extern sdmmc_t sd_sdmmc;
|
||||||
extern sdmmc_storage_t sd_storage;
|
extern sdmmc_storage_t sd_storage;
|
||||||
|
|
||||||
void check_sept()
|
void check_sept(ini_sec_t *cfg_sec)
|
||||||
{
|
{
|
||||||
// Check if non-hekate payload is used for sept and restore it.
|
// Check if non-hekate payload is used for sept and restore it.
|
||||||
if (h_cfg.sept_run)
|
if (h_cfg.sept_run)
|
||||||
|
@ -117,7 +118,7 @@ void check_sept()
|
||||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run)
|
||||||
{
|
{
|
||||||
sdmmc_storage_end(&storage);
|
sdmmc_storage_end(&storage);
|
||||||
reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off, pkg1_id->kb);
|
reboot_to_sept((u8 *)pkg1 + pkg1_id->tsec_off, pkg1_id->kb, cfg_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
|
@ -125,9 +126,10 @@ out_free:
|
||||||
sdmmc_storage_end(&storage);
|
sdmmc_storage_end(&storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
int reboot_to_sept(const u8 *tsec_fw, u32 kb)
|
int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec)
|
||||||
{
|
{
|
||||||
FIL fp;
|
FIL fp;
|
||||||
|
bool fss0_sept_used = false;
|
||||||
|
|
||||||
// Copy warmboot reboot code and TSEC fw.
|
// Copy warmboot reboot code and TSEC fw.
|
||||||
u32 tsec_fw_size = 0x3000;
|
u32 tsec_fw_size = 0x3000;
|
||||||
|
@ -137,36 +139,50 @@ int reboot_to_sept(const u8 *tsec_fw, u32 kb)
|
||||||
memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, tsec_fw_size);
|
memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, tsec_fw_size);
|
||||||
*(vu32 *)SEPT_TCSZ_ADDR = tsec_fw_size;
|
*(vu32 *)SEPT_TCSZ_ADDR = tsec_fw_size;
|
||||||
|
|
||||||
// Copy sept-primary.
|
if (cfg_sec)
|
||||||
if (f_open(&fp, "sept/sept-primary.bin", FA_READ))
|
{
|
||||||
goto error;
|
fss0_sept_t sept_ctxt;
|
||||||
|
sept_ctxt.kb = kb;
|
||||||
|
sept_ctxt.cfg_sec = cfg_sec;
|
||||||
|
sept_ctxt.sept_primary = (void *)SEPT_STG1_ADDR;
|
||||||
|
sept_ctxt.sept_secondary = (void *)SEPT_STG2_ADDR;
|
||||||
|
|
||||||
if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL))
|
fss0_sept_used = load_sept_from_ffs0(&sept_ctxt);
|
||||||
{
|
|
||||||
f_close(&fp);
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
f_close(&fp);
|
|
||||||
|
|
||||||
// Copy sept-secondary.
|
if (!fss0_sept_used)
|
||||||
if (kb < KB_FIRMWARE_VERSION_810)
|
|
||||||
{
|
{
|
||||||
if (f_open(&fp, "sept/sept-secondary_00.enc", FA_READ))
|
// Copy sept-primary.
|
||||||
if (f_open(&fp, "sept/sept-secondary.enc", FA_READ)) // Try the deprecated version.
|
if (f_open(&fp, "sept/sept-primary.bin", FA_READ))
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (f_open(&fp, "sept/sept-secondary_01.enc", FA_READ))
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL))
|
if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL))
|
||||||
{
|
{
|
||||||
|
f_close(&fp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
f_close(&fp);
|
||||||
|
|
||||||
|
// Copy sept-secondary.
|
||||||
|
if (kb < KB_FIRMWARE_VERSION_810)
|
||||||
|
{
|
||||||
|
if (f_open(&fp, "sept/sept-secondary_00.enc", FA_READ))
|
||||||
|
if (f_open(&fp, "sept/sept-secondary.enc", FA_READ)) // Try the deprecated version.
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (f_open(&fp, "sept/sept-secondary_01.enc", FA_READ))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL))
|
||||||
|
{
|
||||||
|
f_close(&fp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
f_close(&fp);
|
|
||||||
|
|
||||||
b_cfg.boot_cfg |= (BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_SEPT_RUN);
|
b_cfg.boot_cfg |= (BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_SEPT_RUN);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
void check_sept();
|
void check_sept(ini_sec_t *cfg_sec);
|
||||||
int reboot_to_sept(const u8 *tsec_fw, u32 kb);
|
int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -529,7 +529,7 @@ void ini_list_launcher()
|
||||||
payload_path = ini_check_payload_section(cfg_sec);
|
payload_path = ini_check_payload_section(cfg_sec);
|
||||||
|
|
||||||
if (cfg_sec && !payload_path)
|
if (cfg_sec && !payload_path)
|
||||||
check_sept();
|
check_sept(cfg_sec);
|
||||||
|
|
||||||
if (!cfg_sec)
|
if (!cfg_sec)
|
||||||
{
|
{
|
||||||
|
@ -656,7 +656,7 @@ void launch_firmware()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_sec && !payload_path)
|
if (cfg_sec && !payload_path)
|
||||||
check_sept();
|
check_sept(cfg_sec);
|
||||||
|
|
||||||
if (!cfg_sec)
|
if (!cfg_sec)
|
||||||
{
|
{
|
||||||
|
@ -793,7 +793,7 @@ static void _auto_launch_firmware()
|
||||||
{
|
{
|
||||||
if (!h_cfg.sept_run)
|
if (!h_cfg.sept_run)
|
||||||
EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD;
|
EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD;
|
||||||
check_sept();
|
check_sept(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!h_cfg.sept_run)
|
if (!h_cfg.sept_run)
|
||||||
|
@ -1055,7 +1055,7 @@ skip_list:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
check_sept();
|
check_sept(cfg_sec);
|
||||||
hos_launch(cfg_sec);
|
hos_launch(cfg_sec);
|
||||||
|
|
||||||
EPRINTF("\nFailed to launch HOS!");
|
EPRINTF("\nFailed to launch HOS!");
|
||||||
|
|
Loading…
Reference in a new issue