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:
CTCaer 2019-12-16 00:53:22 +02:00
parent 9b2d906648
commit 8584493c7f
8 changed files with 120 additions and 61 deletions

View file

@ -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. |

View file

@ -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;

View file

@ -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,12 +104,13 @@ 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;
if (!sept_ctxt)
ctxt->atmosphere = true; ctxt->atmosphere = true;
void *fss = malloc(f_size(&fp)); void *fss = malloc(f_size(&fp));
@ -135,6 +137,8 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path)
continue; continue;
// Load content to launch context. // Load content to launch context.
if (!sept_ctxt)
{
switch (curr_fss_cnt[i].type) switch (curr_fss_cnt[i].type)
{ {
case CNT_TYPE_KIP: case CNT_TYPE_KIP:
@ -155,9 +159,26 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path)
break; break;
default: default:
continue; continue;
// TODO: add more types? }
// case CNT_TYPE_SP1: }
// case CNT_TYPE_SP2: else
{
// Load content to launch context.
switch (curr_fss_cnt[i].type)
{
case CNT_TYPE_SP1:
memcpy(sept_ctxt->sept_primary, content, curr_fss_cnt[i].size);
break;
case CNT_TYPE_SP2:
if (!memcmp(curr_fss_cnt[i].name, (sept_ctxt->kb < KB_FIRMWARE_VERSION_810) ? "septsecondary00" : "septsecondary01", 15))
{
memcpy(sept_ctxt->sept_secondary, content, curr_fss_cnt[i].size);
sept_used = 1;
}
break;
default:
continue;
}
} }
f_lseek(&fp, curr_fss_cnt[i].offset); f_lseek(&fp, curr_fss_cnt[i].offset);
@ -169,7 +190,7 @@ 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);
@ -177,3 +198,14 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path)
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;
}

View file

@ -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

View file

@ -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

View file

@ -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,6 +139,19 @@ 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;
if (cfg_sec)
{
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;
fss0_sept_used = load_sept_from_ffs0(&sept_ctxt);
}
if (!fss0_sept_used)
{
// Copy sept-primary. // Copy sept-primary.
if (f_open(&fp, "sept/sept-primary.bin", FA_READ)) if (f_open(&fp, "sept/sept-primary.bin", FA_READ))
goto error; goto error;
@ -167,6 +182,7 @@ int reboot_to_sept(const u8 *tsec_fw, u32 kb)
goto error; goto error;
} }
f_close(&fp); 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);

View file

@ -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

View file

@ -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!");