forked from Mirrors/usk
(hopefully) permanently fix booting OFW. see changelog of 2.81 release for more information
This commit is contained in:
parent
6cecd25f22
commit
c5599609fb
3 changed files with 96 additions and 28 deletions
|
|
@ -70,7 +70,8 @@ bool wait_for_boot(int timeout_ms) {
|
||||||
|
|
||||||
// properly clean up all state machines before retrying
|
// properly clean up all state machines before retrying
|
||||||
// original deinit only disabled SM 0 and 1, but SM 2 (G_DAT0_SM) was left running
|
// original deinit only disabled SM 0 and 1, but SM 2 (G_DAT0_SM) was left running
|
||||||
pio_set_sm_mask_enabled(pio1, 0x7, false); // Disable SM 0, 1, AND 2 (0x7 = 0b111)
|
|
||||||
|
pio_set_sm_mask_enabled(pio1, 0x7, false); // disable SM 0, 1, AND 2 (0x7 = 0b111)
|
||||||
|
|
||||||
// clean up GPIO pins
|
// clean up GPIO pins
|
||||||
for (int i = PIN_CLK; i <= PIN_DAT; i++)
|
for (int i = PIN_CLK; i <= PIN_DAT; i++)
|
||||||
|
|
|
||||||
2
config.h
2
config.h
|
|
@ -4,7 +4,7 @@
|
||||||
#define OFFSET_MAX 6950
|
#define OFFSET_MAX 6950
|
||||||
|
|
||||||
#define VER_HI 2
|
#define VER_HI 2
|
||||||
#define VER_LO 80
|
#define VER_LO 81
|
||||||
|
|
||||||
bool is_configured();
|
bool is_configured();
|
||||||
void init_config();
|
void init_config();
|
||||||
|
|
|
||||||
67
payload.c
67
payload.c
|
|
@ -708,6 +708,69 @@ void prepare_mariko_bct()
|
||||||
memcpy(data_bct + 0x480, mariko_bct_data, 0x2380);
|
memcpy(data_bct + 0x480, mariko_bct_data, 0x2380);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Atmosphere's fs_mitm (fsmitm_boot0storage.cpp) intercepts all BOOT0 writes and
|
||||||
|
* drops writes to BctNormalMain (offset 0x0000) and BctSafeMain (offset 0x4000)
|
||||||
|
* when it detects the modchip's custom public key fill pattern (0x59, 0x69...) in those
|
||||||
|
* slots. this is by design for AutoRCM preservation, but it means that after a firmware
|
||||||
|
* update via syscfw, UpdateBootImages successfully writes the new BCT to BctNormalSub (0x8000) and BctSafeSub (0xC000),
|
||||||
|
* but the writes to BctNormalMain and BctSafeMain are discarded. the result is that Main slots still hold the modchip
|
||||||
|
* synthetic/fake BCT while Sub slots have the new firmware's real BCT.
|
||||||
|
*
|
||||||
|
* when hekate subsequently tries to launch OFW it reads BctNormalMain, which still points
|
||||||
|
* to the payload area (block 0x1F80) instead of the real pkg1, so OFW fails to boot.
|
||||||
|
*
|
||||||
|
* this function detects that diverged state and resyncs by copying Sub > Main for both
|
||||||
|
* Normal and Safe BCT pairs, restoring them to a consistent state before we overwrite
|
||||||
|
* Main with the synthetic/fake BCT again on this boot.
|
||||||
|
*
|
||||||
|
* detection: read block+1 of each BCT (BCT byte offset 0x220) and compare against the
|
||||||
|
* modchip magic values:
|
||||||
|
* erista: 0x69696969 (pubkey fill area spans BCT bytes 0x211-0x30E, 0x220 is within)
|
||||||
|
* mariko: 0xA56CA203 (first 4 bytes of mariko_bct_sign placed at BCT offset 0x220)
|
||||||
|
*
|
||||||
|
* BOOT0 block layout (512-byte blocks):
|
||||||
|
* BctNormalMain: 0x000-0x01F (BOOT0 byte offset 0x0000, BCT block 0 = BOOT0 block 0x000)
|
||||||
|
* BctSafeMain: 0x020-0x03F (BOOT0 byte offset 0x4000, BCT block 0 = BOOT0 block 0x020)
|
||||||
|
* BctNormalSub: 0x040-0x05F (BOOT0 byte offset 0x8000, BCT block 0 = BOOT0 block 0x040)
|
||||||
|
* BctSafeSub: 0x060-0x07F (BOOT0 byte offset 0xC000, BCT block 0 = BOOT0 block 0x060)
|
||||||
|
*
|
||||||
|
* magic is at BCT byte 0x220 = block-relative offset 0x20 within BCT block 1.
|
||||||
|
* so we read BOOT0 block (bct_start + 1) and check data_buf[0x20].
|
||||||
|
*/
|
||||||
|
static bool bct_block_has_modchip_magic(int bct_start_block) {
|
||||||
|
if (!cmd_mmc_read(bct_start_block + 1) && !cmd_mmc_read(bct_start_block + 1))
|
||||||
|
return false; // read failure; assume no magic, don't resync
|
||||||
|
uint32_t magic = *(uint32_t *)(data_buf + 0x20);
|
||||||
|
return magic == (mariko ? 0xA56CA203 : 0x69696969);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_and_resync_bct() {
|
||||||
|
// only relevant on a configured boot where space_bl magic is already present,
|
||||||
|
// meaning write_payload has previously run and wrote the synthetic/fake BCT.
|
||||||
|
// if the chip is not yet configured there is nothing to resync.
|
||||||
|
if (!is_space_bl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check Normal BCT pair; Main has magic, Sub does not > Sub has a newer Nintendo BCT
|
||||||
|
bool normal_main_magic = bct_block_has_modchip_magic(0x000);
|
||||||
|
bool normal_sub_magic = bct_block_has_modchip_magic(0x040);
|
||||||
|
|
||||||
|
if (normal_main_magic && !normal_sub_magic) {
|
||||||
|
// BctNormalSub was updated by a firmware update but BctNormalMain write was
|
||||||
|
// dropped by Atmosphere. copy Sub > Main to resync.
|
||||||
|
copy_bct(0x040, 0x000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check Safe BCT pair; uses same logic
|
||||||
|
bool safe_main_magic = bct_block_has_modchip_magic(0x020);
|
||||||
|
bool safe_sub_magic = bct_block_has_modchip_magic(0x060);
|
||||||
|
|
||||||
|
if (safe_main_magic && !safe_sub_magic) {
|
||||||
|
copy_bct(0x060, 0x020);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void write_payload() {
|
void write_payload() {
|
||||||
static bool prepared = false;
|
static bool prepared = false;
|
||||||
if (!prepared)
|
if (!prepared)
|
||||||
|
|
@ -720,6 +783,10 @@ void write_payload() {
|
||||||
}
|
}
|
||||||
start_mmc();
|
start_mmc();
|
||||||
reinit_mmc();
|
reinit_mmc();
|
||||||
|
// resync BctNormalMain/BctSafeMain from their Sub counterparts if Atmosphere's
|
||||||
|
// fs_mitm has silently dropped writes to Main during a syscfw firmware update.
|
||||||
|
// *has to* run before copy_bct backs up Main, so the backup captures the correct state.
|
||||||
|
check_and_resync_bct();
|
||||||
if (!is_space_bl && !is_command)
|
if (!is_space_bl && !is_command)
|
||||||
{
|
{
|
||||||
copy_bct(0x0, 0x7A0);
|
copy_bct(0x0, 0x7A0);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue