Do not always reboot to HM when autobooting HB
Also fix CRC calculation
This commit is contained in:
parent
9957d6db1a
commit
5a5332a212
@ -28,10 +28,11 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "fs.h"
|
||||||
|
|
||||||
u8 *loadDeliverArg(void)
|
u8 *loadDeliverArg(void)
|
||||||
{
|
{
|
||||||
static u8 deliverArg[0x1000] = {0};
|
static __attribute__((aligned(8))) u8 deliverArg[0x1000] = {0};
|
||||||
static bool deliverArgLoaded = false;
|
static bool deliverArgLoaded = false;
|
||||||
|
|
||||||
if (!deliverArgLoaded)
|
if (!deliverArgLoaded)
|
||||||
@ -50,8 +51,11 @@ u8 *loadDeliverArg(void)
|
|||||||
|
|
||||||
// Validate deliver arg
|
// Validate deliver arg
|
||||||
u32 testPattern = *(u32 *)(deliverArg + 0x438);
|
u32 testPattern = *(u32 *)(deliverArg + 0x438);
|
||||||
u32 crc = *(u32 *)(deliverArg + 0x43C);
|
u32 *crcPtr = (u32 *)(deliverArg + 0x43C);
|
||||||
|
u32 crc = *crcPtr;
|
||||||
|
*crcPtr = 0; // clear crc field before calculation
|
||||||
u32 expectedCrc = crc32(deliverArg + 0x400, 0x140, 0xFFFFFFFF);
|
u32 expectedCrc = crc32(deliverArg + 0x400, 0x140, 0xFFFFFFFF);
|
||||||
|
*crcPtr = crc;
|
||||||
if (testPattern != 0xFFFF || crc != expectedCrc)
|
if (testPattern != 0xFFFF || crc != expectedCrc)
|
||||||
memset(deliverArg, 0, 0x1000);
|
memset(deliverArg, 0, 0x1000);
|
||||||
}
|
}
|
||||||
@ -93,6 +97,7 @@ void commitDeliverArg(void)
|
|||||||
if (mode == 0) // CTR mode
|
if (mode == 0) // CTR mode
|
||||||
{
|
{
|
||||||
*(u32 *)(deliverArg + 0x438) = 0xFFFF;
|
*(u32 *)(deliverArg + 0x438) = 0xFFFF;
|
||||||
|
*(u32 *)(deliverArg + 0x43C) = 0; // clear CRC field before calculating it
|
||||||
*(u32 *)(deliverArg + 0x43C) = crc32(deliverArg + 0x400, 0x140, 0xFFFFFFFF);
|
*(u32 *)(deliverArg + 0x43C) = crc32(deliverArg + 0x400, 0x140, 0xFFFFFFFF);
|
||||||
memcpy((void *)0x20000000, deliverArg, 0x1000);
|
memcpy((void *)0x20000000, deliverArg, 0x1000);
|
||||||
}
|
}
|
||||||
@ -185,9 +190,27 @@ bool configureHomebrewAutoboot(void)
|
|||||||
u32 bootenv = CFG_BOOTENV;
|
u32 bootenv = CFG_BOOTENV;
|
||||||
u32 mode = bootenv >> 1;
|
u32 mode = bootenv >> 1;
|
||||||
|
|
||||||
u32 testPattern = *(u32 *)(deliverArg + 0x438);
|
// NS always writes a valid deliver arg on reboot, no matter what.
|
||||||
if (mode != 0 || testPattern == 0xFFFF)
|
// Check if it is empty, and, of course, bail out if we aren't rebooting from
|
||||||
return false; // bail out if this isn't a coldboot/plain reboot
|
// NATIVE_FIRM.
|
||||||
|
// Checking if it is empty is necessary to let us reboot from autobooted hbmenu
|
||||||
|
// to hbmenu.
|
||||||
|
|
||||||
|
if (mode != 0)
|
||||||
|
return false;
|
||||||
|
else if (bootenv == 1)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < 0x410; i++)
|
||||||
|
{
|
||||||
|
if (deliverArg[i] != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (u32 i = 0x440; i < 0x1000; i++)
|
||||||
|
{
|
||||||
|
if (deliverArg[i] != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (MULTICONFIG(AUTOBOOTMODE))
|
switch (MULTICONFIG(AUTOBOOTMODE))
|
||||||
{
|
{
|
||||||
|
@ -229,12 +229,19 @@ void main(int argc, char **argv, u32 magicWord)
|
|||||||
nandType = FIRMWARE_SYSNAND;
|
nandType = FIRMWARE_SYSNAND;
|
||||||
firmSource = (BOOTCFG_NAND != 0) == (BOOTCFG_FIRM != 0) ? FIRMWARE_SYSNAND : (FirmwareSource)BOOTCFG_FIRM;
|
firmSource = (BOOTCFG_NAND != 0) == (BOOTCFG_FIRM != 0) ? FIRMWARE_SYSNAND : (FirmwareSource)BOOTCFG_FIRM;
|
||||||
|
|
||||||
//Prevent multiple boot options-forcing
|
// Prevent multiple boot options-forcing
|
||||||
|
// This bit is a bit weird. Basically, as you return to Home Menu by pressing either
|
||||||
|
// the HOME or POWER button, nandType will be overridden to "SysNAND" (needed). But,
|
||||||
|
// if you reboot again (e.g. via Rosalina menu), it'll use your default settings.
|
||||||
if(nandType != BOOTCFG_NAND || firmSource != BOOTCFG_FIRM) isNoForceFlagSet = true;
|
if(nandType != BOOTCFG_NAND || firmSource != BOOTCFG_FIRM) isNoForceFlagSet = true;
|
||||||
|
|
||||||
goto boot;
|
goto boot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Configure homebrew autoboot (if deliver arg ends up not containing anything)
|
||||||
|
if (bootenv == 1 && MULTICONFIG(AUTOBOOTMODE) != 0)
|
||||||
|
configureHomebrewAutoboot();
|
||||||
|
|
||||||
/* Force the last used boot options if doing autolaunch from TWL, or unless a button is pressed
|
/* Force the last used boot options if doing autolaunch from TWL, or unless a button is pressed
|
||||||
or the no-forcing flag is set */
|
or the no-forcing flag is set */
|
||||||
if(validTlnc || !(pressed || BOOTCFG_NOFORCEFLAG))
|
if(validTlnc || !(pressed || BOOTCFG_NOFORCEFLAG))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user