forked from Mirror/SafeB9SInstaller
Replaced the emergency chainloader with an auto restore feature
This commit is contained in:
parent
1dd5e8785d
commit
ab6240da42
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#define PAYLOAD_MAX_SIZE 0xFFFE0
|
|
||||||
|
|
||||||
void Chainload(u8 *source, size_t size);
|
|
@ -1,52 +0,0 @@
|
|||||||
@ Wolfvak - 25/01/2017
|
|
||||||
|
|
||||||
@ TODO: ELF launcher
|
|
||||||
@ void Chainload(u8 *source, size_t size)
|
|
||||||
@ Wrapper around chainload_itcm
|
|
||||||
|
|
||||||
.arm
|
|
||||||
.global Chainload
|
|
||||||
.type Chainload, %function
|
|
||||||
Chainload:
|
|
||||||
ldr r2, =0x1FF8100 @ ITCM + 0x100 bytes
|
|
||||||
mov r3, r2
|
|
||||||
ldr r4, =chainload_itcm
|
|
||||||
ldr r5, =chainload_itcm_end
|
|
||||||
|
|
||||||
.copy_chainloader:
|
|
||||||
cmp r4, r5
|
|
||||||
ldrlt r6, [r4], #4
|
|
||||||
strlt r6, [r3], #4
|
|
||||||
blt .copy_chainloader
|
|
||||||
|
|
||||||
bx r2 @ Branch to the real chainloader in ITCM
|
|
||||||
|
|
||||||
|
|
||||||
@ void chainload_itcm(void)
|
|
||||||
@ Note: Uses unprotected bootrom functions
|
|
||||||
.arm
|
|
||||||
.type chainload_itcm, %function
|
|
||||||
.align 4
|
|
||||||
chainload_itcm:
|
|
||||||
mov r2, r1
|
|
||||||
ldr r1, =0x23F00000
|
|
||||||
|
|
||||||
mov r4, r1 @ memcpy256 and clean_flush_cache mess with the registers
|
|
||||||
|
|
||||||
ldr r3, =0xFFFF03F0 @ memcpy256(u32 *src, u32 *ddest, size_t size)
|
|
||||||
blx r3
|
|
||||||
|
|
||||||
ldr r3, =0xFFFF0830 @ void clean_flush_cache(void)
|
|
||||||
blx r3
|
|
||||||
|
|
||||||
mov r3, r4
|
|
||||||
|
|
||||||
mov r0, #0 @ Clear argc
|
|
||||||
mov r1, #0 @ Same for argv
|
|
||||||
mov r2, #0
|
|
||||||
mov lr, #0
|
|
||||||
bx r3
|
|
||||||
|
|
||||||
.pool
|
|
||||||
|
|
||||||
chainload_itcm_end:
|
|
@ -41,7 +41,7 @@
|
|||||||
#define ENTRY_GATEWAY (2)
|
#define ENTRY_GATEWAY (2)
|
||||||
|
|
||||||
// SafeB9SInstaller version
|
// SafeB9SInstaller version
|
||||||
#define VERSION "0.0.5"
|
#define VERSION "0.0.6"
|
||||||
|
|
||||||
// testfing flags, only useful to devs
|
// testfing flags, only useful to devs
|
||||||
// #define NO_WRITE // disables all NAND writes, just for testing
|
// #define NO_WRITE // disables all NAND writes, just for testing
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "installer.h"
|
#include "installer.h"
|
||||||
#include "validator.h"
|
|
||||||
#include "safewrite.h"
|
#include "safewrite.h"
|
||||||
#include "chainload.h"
|
#include "validator.h"
|
||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "qff.h"
|
#include "qff.h"
|
||||||
@ -20,6 +19,7 @@
|
|||||||
#define NAME_SECTOR0x96 (IS_DEVKIT ? INPUT_PATH "/secret_sector_dev.bin" : INPUT_PATH "/secret_sector.bin")
|
#define NAME_SECTOR0x96 (IS_DEVKIT ? INPUT_PATH "/secret_sector_dev.bin" : INPUT_PATH "/secret_sector.bin")
|
||||||
#define NAME_FIRMBACKUP INPUT_PATH "/firm0firm1.bak"
|
#define NAME_FIRMBACKUP INPUT_PATH "/firm0firm1.bak"
|
||||||
#define NAME_SECTORBACKUP INPUT_PATH "/sector0x96.bak"
|
#define NAME_SECTORBACKUP INPUT_PATH "/sector0x96.bak"
|
||||||
|
#define NAME_PAYLOAD INPUT_PATH "/payload.firm"
|
||||||
|
|
||||||
#define STATUS_GREY -1
|
#define STATUS_GREY -1
|
||||||
#define STATUS_GREEN 0
|
#define STATUS_GREEN 0
|
||||||
@ -294,30 +294,52 @@ u32 SafeB9SInstaller(void) {
|
|||||||
|
|
||||||
// if we end up here: uhoh
|
// if we end up here: uhoh
|
||||||
ShowPrompt(false, "SafeB9SInstaller failed!\nThis really should not have happened :/.");
|
ShowPrompt(false, "SafeB9SInstaller failed!\nThis really should not have happened :/.");
|
||||||
ShowPrompt(false, "You may launch an external payload\nto try and fix up your system.\n \nThis may be your LAST CHANCE!\nUse it wisely.");
|
ShowPrompt(false, "Your system is now reverted to\nit's earlier state.\n \nDO NOT TURN OFF YOUR 3DS NOW!");
|
||||||
const char* optionstr[2] = { "Unmount SD card", "Run " INPUT_PATH "/payload.bin" };
|
|
||||||
while (true) {
|
|
||||||
u32 user_select = ShowSelectPrompt(2, optionstr, "Make your choice.");
|
|
||||||
if (user_select == 1) {
|
|
||||||
fs_deinit();
|
|
||||||
ShowString("SD card unmounted, you can eject now.\n \n<A> to remount SD card");
|
|
||||||
while (true) {
|
|
||||||
u32 pad_choice = InputWait();
|
|
||||||
if (!(pad_choice & BUTTON_A)) continue;
|
|
||||||
if (fs_init() == FR_OK) break;
|
|
||||||
ShowString("Reinitialising SD card failed!\n \n<A> to retry");
|
|
||||||
}
|
|
||||||
} else if (user_select == 2) {
|
|
||||||
UINT payload_size;
|
|
||||||
if ((f_qread(INPUT_PATH "/payload.bin", WORK_BUFFER, 0, WORK_BUFFER_SIZE, &payload_size) != FR_OK) ||
|
|
||||||
!payload_size || (payload_size > PAYLOAD_MAX_SIZE))
|
|
||||||
continue;
|
|
||||||
if (ShowUnlockSequence(3, "payload.bin (%dkB)\nLaunch as arm9 payload?", payload_size / 1024)) {
|
|
||||||
Chainload(WORK_BUFFER, payload_size);
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
// try to revert to the earlier state
|
||||||
|
snprintf(msgBackup, 64, "FIRM restore...");
|
||||||
|
statusBackup = STATUS_YELLOW;
|
||||||
|
ShowInstallerStatus();
|
||||||
|
if (f_open(&fp, NAME_FIRMBACKUP, FA_READ|FA_OPEN_EXISTING) != FR_OK) {
|
||||||
|
snprintf(msgBackup, 64, "FIRM restore fail");
|
||||||
|
statusBackup = STATUS_RED;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ShowProgress(0, 0, "FIRM restore");
|
||||||
|
for (u32 pos = 0; (pos < FIRM_NAND_SIZE) && (ret == 0); pos += WORK_BUFFER_SIZE) {
|
||||||
|
UINT bytes = min(WORK_BUFFER_SIZE, FIRM_NAND_SIZE - pos);
|
||||||
|
snprintf(msgBackup, 64, "FIRM restore (%luMB/%luMB)",
|
||||||
|
pos / (1024*1024), (u32) FIRM_NAND_SIZE / (1024 * 1024));
|
||||||
|
ShowInstallerStatus();
|
||||||
|
if ((f_read(&fp, WORK_BUFFER, bytes, &bt) != FR_OK) || (bt != bytes) ||
|
||||||
|
(WriteNandBytes(WORK_BUFFER, FIRM_NAND_OFFSET + pos, bytes, 0xFF) != 0))
|
||||||
|
ret = 1;
|
||||||
|
ShowProgress(pos + bytes, FIRM_NAND_SIZE, "FIRM restore");
|
||||||
|
}
|
||||||
|
f_close(&fp);
|
||||||
|
if (ret != 0) {
|
||||||
|
snprintf(msgBackup, 64, "FIRM restore fail");
|
||||||
|
statusBackup = STATUS_RED;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((IS_A9LH && !IS_SIGHAX)) {
|
||||||
|
snprintf(msgBackup, 64, "0x96 restore...");
|
||||||
|
ShowInstallerStatus();
|
||||||
|
u8 sector_backup[0x200];
|
||||||
|
if ((f_qread(NAME_SECTORBACKUP, sector_backup, 0, 0x200, &bt) != FR_OK) || (bt != 0x200) ||
|
||||||
|
(WriteNandSectors(sector_backup, 0x96, 1, 0xFF) != 0)) {
|
||||||
|
snprintf(msgBackup, 64, "0x96 restore fail");
|
||||||
|
statusBackup = STATUS_RED;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
snprintf(msgA9lh, 64, "restored a9lh");
|
||||||
|
statusA9lh = STATUS_YELLOW;
|
||||||
|
}
|
||||||
|
snprintf(msgBackup, 64, "backup restored");
|
||||||
|
statusBackup = STATUS_YELLOW;
|
||||||
|
snprintf(msgInstall, 64, "reverted system");
|
||||||
|
statusInstall = STATUS_YELLOW;
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user