forked from Mirror/GodMode9
Improved ntrboot checks
... this also restores default behaviour when booting from ntrboot and simplifies the bootloader behaviour.
This commit is contained in:
parent
a92c993573
commit
dcafbaa191
@ -32,8 +32,6 @@ To build a .firm signed with SPI boot keys (for ntrboot and the like), run `make
|
|||||||
## Bootloader mode / NTRboot mode
|
## Bootloader mode / NTRboot mode
|
||||||
Same as [boot9strap](https://github.com/SciresM/boot9strap), GodMode9 can be installed to the system FIRM partition ('FIRM0'). When executed from a FIRM partition, GodMode9 will default to bootloader mode and try to boot, in order, `FIRM from FCRAM` (see [A9NC](https://github.com/d0k3/A9NC/releases), `0:/bootonce.firm` (will be deleted on a successful boot), `0:/boot.firm`, `1:/boot.firm`. In bootloader mode, hold R+LEFT on boot to enter the boot menu. *Installing GodMode9 to a FIRM partition is only recommended for developers and will overwrite [boot9strap](https://github.com/SciresM/boot9strap)*.
|
Same as [boot9strap](https://github.com/SciresM/boot9strap), GodMode9 can be installed to the system FIRM partition ('FIRM0'). When executed from a FIRM partition, GodMode9 will default to bootloader mode and try to boot, in order, `FIRM from FCRAM` (see [A9NC](https://github.com/d0k3/A9NC/releases), `0:/bootonce.firm` (will be deleted on a successful boot), `0:/boot.firm`, `1:/boot.firm`. In bootloader mode, hold R+LEFT on boot to enter the boot menu. *Installing GodMode9 to a FIRM partition is only recommended for developers and will overwrite [boot9strap](https://github.com/SciresM/boot9strap)*.
|
||||||
|
|
||||||
When flashed directly to a [NTRboot](https://github.com/kitling/ntrboot_flasher) compatible flashcard, GodMode9 will default to ntrboot mode, which is the same as bootloader mode but automatically enters the boot menu.
|
|
||||||
|
|
||||||
|
|
||||||
## Write permissions system
|
## Write permissions system
|
||||||
GodMode9 provides a write permissions system, which will protect you from accidentually damaging you system, losing data and/or modifying important system data. To unlock a write permission, an unlock sequence must be entered. This is not possible by accident. The write permission system is based on colors and the top bar on the top screen will change color according to the current write permission level. No permission above the yellow level can be unlocked on SafeMode9.
|
GodMode9 provides a write permissions system, which will protect you from accidentually damaging you system, losing data and/or modifying important system data. To unlock a write permission, an unlock sequence must be entered. This is not possible by accident. The write permission system is based on colors and the top bar on the top screen will change color according to the current write permission level. No permission above the yellow level can be unlocked on SafeMode9.
|
||||||
|
@ -13,5 +13,5 @@ SECTIONS
|
|||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|
||||||
__stack_top = 0x1FFFF800;
|
__stack_top = 0x1FFFE000;
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,6 @@
|
|||||||
// see: https://www.3dbrew.org/wiki/OTP_Registers#Plaintext_OTP
|
// see: https://www.3dbrew.org/wiki/OTP_Registers#Plaintext_OTP
|
||||||
#define IS_DEVKIT ((*(vu8*) (0x01FFB800+0x19)) != 0x0)
|
#define IS_DEVKIT ((*(vu8*) (0x01FFB800+0x19)) != 0x0)
|
||||||
|
|
||||||
// check first 8 byte of NTRBOOT blowfish data (0x6A0 in DTCM)
|
|
||||||
#define IS_NTRBOOT ((*(vu64*) (0x300086A0)) == 0xBFEFD1CD2683A24E)
|
|
||||||
|
|
||||||
// see: https://3dbrew.org/wiki/CONFIG11_Registers
|
// see: https://3dbrew.org/wiki/CONFIG11_Registers
|
||||||
// (also returns true for sighaxed systems, maybe change the name later?)
|
// (also returns true for sighaxed systems, maybe change the name later?)
|
||||||
#define IS_A9LH ((*(vu32*) 0x101401C0) == 0)
|
#define IS_A9LH ((*(vu32*) 0x101401C0) == 0)
|
||||||
|
@ -1638,9 +1638,9 @@ u32 GodMode(bool is_b9s) {
|
|||||||
u32 cursor = 0;
|
u32 cursor = 0;
|
||||||
u32 scroll = 0;
|
u32 scroll = 0;
|
||||||
|
|
||||||
bool bootloader = !is_b9s && IS_SIGHAX; // only when installed to FIRM / on NTRBOOT
|
u32 boot_origin = GetBootOrigin();
|
||||||
bool ntrboot = bootloader && IS_NTRBOOT;
|
bool bootloader = !is_b9s && IS_SIGHAX && (boot_origin & BOOT_NAND);
|
||||||
bool bootmenu = bootloader && (ntrboot || CheckButton(BOOTMENU_KEY));
|
bool bootmenu = bootloader && CheckButton(BOOTMENU_KEY);
|
||||||
bool godmode9 = !bootloader;
|
bool godmode9 = !bootloader;
|
||||||
FirmHeader* firm_in_mem = (FirmHeader*) DIR_BUFFER;
|
FirmHeader* firm_in_mem = (FirmHeader*) DIR_BUFFER;
|
||||||
memcpy(firm_in_mem, "NOPE", 4); // to prevent bootloops
|
memcpy(firm_in_mem, "NOPE", 4); // to prevent bootloops
|
||||||
@ -1653,11 +1653,12 @@ u32 GodMode(bool is_b9s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* disp_mode =
|
// get mode string for splash screen
|
||||||
ntrboot ? "ntrboot mode" :
|
const char* disp_mode = NULL;
|
||||||
bootmenu ? "bootmenu mode" :
|
if (bootloader) disp_mode = "bootloader mode";
|
||||||
bootloader ? "bootloader mode" :
|
else if (!is_b9s && !IS_SIGHAX) disp_mode = "oldloader mode";
|
||||||
!is_b9s ? "oldloader mode" : NULL;
|
else if (!is_b9s && IS_SIGHAX && (boot_origin & BOOT_NTRBOOT)) disp_mode = "ntrboot mode";
|
||||||
|
// else if (!is_b9s || !IS_SIGHAX) disp_mode = "unknown mode";
|
||||||
|
|
||||||
ClearScreenF(true, true, COLOR_STD_BG);
|
ClearScreenF(true, true, COLOR_STD_BG);
|
||||||
SplashInit(disp_mode);
|
SplashInit(disp_mode);
|
||||||
@ -1703,6 +1704,7 @@ u32 GodMode(bool is_b9s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef AL3X10MODE
|
#ifndef AL3X10MODE
|
||||||
|
bootmenu = bootloader && CheckButton(BOOTMENU_KEY); // second check for boot menu keys
|
||||||
while (HID_STATE & BUTTON_ANY); // don't continue while any button is held
|
while (HID_STATE & BUTTON_ANY); // don't continue while any button is held
|
||||||
#endif
|
#endif
|
||||||
while (timer_msec( timer ) < 500); // show splash for at least 0.5 sec
|
while (timer_msec( timer ) < 500); // show splash for at least 0.5 sec
|
||||||
|
@ -534,6 +534,30 @@ u32 GetNandPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 ind
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetBootOrigin(void)
|
||||||
|
{
|
||||||
|
// see: https://github.com/AuroraWright/Luma3DS/blob/bc1aa15dd709a703b9af1a0f89ccded21fc08823/source/main.c#L58-L62
|
||||||
|
// and: https://www.3dbrew.org/wiki/Bootloader#BootROM_Errors
|
||||||
|
const vu8* bootMediaStatus = (vu8*) 0x1FFFE00C;
|
||||||
|
const vu8* bootNcsdStatus = (vu8*) 0x1FFFE010;
|
||||||
|
|
||||||
|
if (!*(u64*) (void*) bootNcsdStatus) { // no NAND boot
|
||||||
|
bool ntrboot_ok = !(bootMediaStatus[1]);
|
||||||
|
bool shell_closed = (bootMediaStatus[3] == 2); // unsure of meaning(!)
|
||||||
|
if (ntrboot_ok && shell_closed) return BOOT_NTRBOOT;
|
||||||
|
} else if (!bootMediaStatus[0]) { // NAND boot okay, check partitions boot state
|
||||||
|
int n_boot_firm = -1;
|
||||||
|
for (u32 i = 0; i < 8; i++) {
|
||||||
|
if (bootNcsdStatus[i] != 0) continue; // not booted from here, continue
|
||||||
|
if (n_boot_firm >= 0) return BOOT_UNKNOWN; // booted from 2+ partitions?
|
||||||
|
n_boot_firm = i;
|
||||||
|
}
|
||||||
|
if (n_boot_firm >= 0) return BOOT_NAND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BOOT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
bool CheckMultiEmuNand(void)
|
bool CheckMultiEmuNand(void)
|
||||||
{
|
{
|
||||||
// this only checks for the theoretical possibility
|
// this only checks for the theoretical possibility
|
||||||
|
@ -7,6 +7,11 @@
|
|||||||
#define NAND_IMGNAND (1UL<<2)
|
#define NAND_IMGNAND (1UL<<2)
|
||||||
#define NAND_ZERONAND (1UL<<3)
|
#define NAND_ZERONAND (1UL<<3)
|
||||||
|
|
||||||
|
#define BOOT_UNKNOWN 0
|
||||||
|
#define BOOT_NAND (1UL<<0)
|
||||||
|
#define BOOT_NTRBOOT (1UL<<1)
|
||||||
|
#define BOOT_WIFI_SPI (1UL<<2)
|
||||||
|
|
||||||
// hardcoded start sectors
|
// hardcoded start sectors
|
||||||
#define SECTOR_D0K3 0x000001
|
#define SECTOR_D0K3 0x000001
|
||||||
#define SECTOR_SECRET 0x000096
|
#define SECTOR_SECRET 0x000096
|
||||||
@ -74,6 +79,7 @@ u32 GetNandMinSizeSectors(u32 nand_src);
|
|||||||
u32 GetNandSizeSectors(u32 nand_src);
|
u32 GetNandSizeSectors(u32 nand_src);
|
||||||
u32 GetNandNcsdPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 index, NandNcsdHeader* ncsd);
|
u32 GetNandNcsdPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 index, NandNcsdHeader* ncsd);
|
||||||
u32 GetNandPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 index, u32 nand_src);
|
u32 GetNandPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 index, u32 nand_src);
|
||||||
|
u32 GetBootOrigin(void);
|
||||||
|
|
||||||
u32 ValidateSecretSector(u8* sector);
|
u32 ValidateSecretSector(u8* sector);
|
||||||
bool CheckMultiEmuNand(void);
|
bool CheckMultiEmuNand(void);
|
||||||
|
@ -175,7 +175,7 @@ u32 InjectGbaVcSavegame(const char* path, const char* path_vcsave) {
|
|||||||
if (FixFileCmac(path) != 0) return 1; // cmac fail (this is not efficient, but w/e)
|
if (FixFileCmac(path) != 0) return 1; // cmac fail (this is not efficient, but w/e)
|
||||||
|
|
||||||
// set CFG_BOOTENV to 0x7 so the save is taken over
|
// set CFG_BOOTENV to 0x7 so the save is taken over
|
||||||
// https://www.3dbrew.org/wiki/CONFIG_Registers#CFG_BOOTENV
|
// https://www.3dbrew.org/wiki/CONFIG9_Registers#CFG9_BOOTENV
|
||||||
if (strncasecmp(path, "S:/agbsave.bin", 256) == 0) *(u32*) 0x10010000 = 0x7;
|
if (strncasecmp(path, "S:/agbsave.bin", 256) == 0) *(u32*) 0x10010000 = 0x7;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -353,7 +353,8 @@ bool init_vars(const char* path_script) {
|
|||||||
set_var("NULL", ""); // this one is special and should not be changed later
|
set_var("NULL", ""); // this one is special and should not be changed later
|
||||||
set_var("CURRDIR", curr_dir); // script path, never changes
|
set_var("CURRDIR", curr_dir); // script path, never changes
|
||||||
set_var("GM9OUT", OUTPUT_PATH); // output path, never changes
|
set_var("GM9OUT", OUTPUT_PATH); // output path, never changes
|
||||||
set_var("HAX", IS_NTRBOOT ? "ntrboot" : IS_SIGHAX ? "sighax" : IS_A9LH ? "a9lh" : ""); // type of hax running from
|
set_var("HAX", ((GetBootOrigin() & BOOT_NTRBOOT) && IS_SIGHAX) ? "ntrboot" :
|
||||||
|
IS_SIGHAX ? "sighax" : IS_A9LH ? "a9lh" : ""); // type of hax running from
|
||||||
set_var("ONTYPE", IS_O3DS ? "O3DS" : "N3DS"); // type of the console
|
set_var("ONTYPE", IS_O3DS ? "O3DS" : "N3DS"); // type of the console
|
||||||
set_var("RDTYPE", IS_DEVKIT ? "devkit" : "retail"); // devkit / retail
|
set_var("RDTYPE", IS_DEVKIT ? "devkit" : "retail"); // devkit / retail
|
||||||
upd_var(NULL); // set all dynamic environment vars
|
upd_var(NULL); // set all dynamic environment vars
|
||||||
|
Loading…
x
Reference in New Issue
Block a user