fatal: reboot to sdmc:/atmosphere/reboot_payload.bin

This commit is contained in:
Michael Scire 2019-01-24 08:20:27 -08:00
parent c6f06e2c40
commit 031c9e545b
7 changed files with 109 additions and 11 deletions

View file

@ -58,9 +58,9 @@ static void SetupConfigLanguages() {
config->error_desc = u8"Please call 1-800-875-1852 for service.\n"; config->error_desc = u8"Please call 1-800-875-1852 for service.\n";
} else { } else {
config->error_desc = u8"An error has occured.\n\n" config->error_desc = u8"An error has occured.\n\n"
u8"Please press the POWER Button to restart the console, or a VOL button\n" u8"Please press the POWER Button to restart the console normally, or a VOL button\n"
u8"to restart the console in RCM mode. If you are unable to restart the\n" u8"to reboot to a payload (or RCM, if none is present). If you are unable to\n"
u8"console, hold the POWER Button for 12 seconds to turn the console off.\n\n" u8"restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n"
u8"If the problem persists, refer to the Nintendo Support Website.\n" u8"If the problem persists, refer to the Nintendo Support Website.\n"
u8"support.nintendo.com/switch/error\n"; u8"support.nintendo.com/switch/error\n";
} }

View file

@ -29,6 +29,7 @@
#include "fatal_config.hpp" #include "fatal_config.hpp"
#include "fatal_repair.hpp" #include "fatal_repair.hpp"
#include "fatal_font.hpp" #include "fatal_font.hpp"
#include "fatal_payload_manager.hpp"
extern "C" { extern "C" {
extern u32 __start__; extern u32 __start__;
@ -159,6 +160,9 @@ int main(int argc, char **argv)
/* Load settings from set:sys. */ /* Load settings from set:sys. */
InitializeFatalConfig(); InitializeFatalConfig();
/* Load a payload from the SD card. */
FatalPayloadManager::LoadPayloadFromSdCard();
/* Load shared font. */ /* Load shared font. */
if (R_FAILED(FontManager::InitializeSharedFont())) { if (R_FAILED(FontManager::InitializeSharedFont())) {
std::abort(); std::abort();

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <switch.h>
#include <stratosphere.hpp>
#include <string.h>
#include "fatal_types.hpp"
#include "fatal_payload_manager.hpp"
/* TODO: Find a way to pre-populate this with the contents of fusee-primary. */
static u8 g_reboot_payload[IRAM_PAYLOAD_MAX_SIZE] __attribute__ ((aligned (0x1000)));
static u8 g_work_page[0x1000] __attribute__ ((aligned (0x1000)));
static bool g_payload_loaded = false;
void FatalPayloadManager::LoadPayloadFromSdCard() {
FILE *f = fopen("sdmc:/atmosphere/reboot_payload.bin", "rb");
if (f == NULL) {
return;
}
ON_SCOPE_EXIT { fclose(f); };
memset(g_reboot_payload, 0xFF, sizeof(g_reboot_payload));
fread(g_reboot_payload, 1, IRAM_PAYLOAD_MAX_SIZE, f);
g_payload_loaded = true;
}
static void ClearIram() {
/* Make page FFs. */
memset(g_work_page, 0xFF, sizeof(g_work_page));
/* Overwrite all of IRAM with FFs. */
for (size_t ofs = 0; ofs < IRAM_PAYLOAD_MAX_SIZE; ofs += sizeof(g_work_page)) {
CopyToIram(IRAM_PAYLOAD_BASE + ofs, g_work_page, sizeof(g_work_page));
}
}
void FatalPayloadManager::RebootToPayload() {
/* If we don't actually have a payload loaded, just go to RCM. */
if (!g_payload_loaded) {
RebootToRcm();
}
/* Ensure clean IRAM state. */
ClearIram();
/* Copy in payload. */
for (size_t ofs = 0; ofs < sizeof(g_reboot_payload); ofs += 0x1000) {
CopyToIram(IRAM_PAYLOAD_BASE + ofs, &g_reboot_payload[ofs], 0x1000);
}
RebootToIramPayload();
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#include <stratosphere.hpp>
#define IRAM_PAYLOAD_MAX_SIZE 0x30000
#define IRAM_PAYLOAD_BASE 0x40010000ull
class FatalPayloadManager {
public:
static void LoadPayloadFromSdCard();
static void RebootToPayload();
};

View file

@ -16,6 +16,7 @@
#include <switch.h> #include <switch.h>
#include "fatal_task_power.hpp" #include "fatal_task_power.hpp"
#include "fatal_payload_manager.hpp"
#include "fatal_config.hpp" #include "fatal_config.hpp"
bool PowerControlTask::TryShutdown() { bool PowerControlTask::TryShutdown() {
@ -123,13 +124,13 @@ void PowerButtonObserveTask::WaitForPowerButton() {
Result rc = 0; Result rc = 0;
if (check_vol_up && R_SUCCEEDED((rc = gpioPadGetValue(&vol_up_btn, &val))) && val == GpioValue_Low) { if (check_vol_up && R_SUCCEEDED((rc = gpioPadGetValue(&vol_up_btn, &val))) && val == GpioValue_Low) {
/* Tell exosphere to reboot to RCM. */ /* Tell exosphere to reboot to payload. */
RebootToRcm(); FatalPayloadManager::RebootToPayload();
} }
if (check_vol_down && R_SUCCEEDED((rc = gpioPadGetValue(&vol_down_btn, &val))) && val == GpioValue_Low) { if (check_vol_down && R_SUCCEEDED((rc = gpioPadGetValue(&vol_down_btn, &val))) && val == GpioValue_Low) {
/* Tell exosphere to reboot to RCM. */ /* Tell exosphere to reboot to payload. */
RebootToRcm(); FatalPayloadManager::RebootToPayload();
} }
if ((R_SUCCEEDED(rc = bpcGetSleepButtonState(&state)) && state == BpcSleepButtonState_Held) || (config->quest_flag && reboot_helper.TimedOut())) { if ((R_SUCCEEDED(rc = bpcGetSleepButtonState(&state)) && state == BpcSleepButtonState_Held) || (config->quest_flag && reboot_helper.TimedOut())) {

View file

@ -215,9 +215,9 @@ Result ShowFatalTask::ShowFatal() {
} else { } else {
/* Print a special message for atmosphere version mismatch. */ /* Print a special message for atmosphere version mismatch. */
FontManager::Print(u8"Atmosphère version mismatch detected.\n\n" FontManager::Print(u8"Atmosphère version mismatch detected.\n\n"
u8"Please press the POWER Button to restart the console, or a VOL button\n" u8"Please press the POWER Button to restart the console normally, or a VOL button\n"
u8"to restart the console in RCM mode. If you are unable to restart the\n" u8"to reboot to a payload (or RCM, if none is present). If you are unable to\n"
u8"console, hold the POWER Button for 12 seconds to turn the console off.\n\n" u8"restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n"
u8"Please ensure that all Atmosphère components are updated.\n" u8"Please ensure that all Atmosphère components are updated.\n"
u8"github.com/Atmosphere-NX/Atmosphere/releases\n"); u8"github.com/Atmosphere-NX/Atmosphere/releases\n");
} }

@ -1 +1 @@
Subproject commit de4c2ddae12207e8ebe5f2f8d40335f0ebd9858d Subproject commit 9bf228de3e1e33ea62ed18b51853e5de6b4c4b41