Magical Backup

This commit is contained in:
devdl11
2022-05-19 19:50:27 +02:00
parent 833bc4a120
commit 8e543f30c9
22 changed files with 265 additions and 21 deletions

View File

@@ -37,6 +37,7 @@ bootloader_src += $(addprefix bootloader/interface/menus/, \
warning.cpp \
slot_recovery.cpp \
crash.cpp \
upsilon_recovery.cpp \
)
bootloader_images = $(addprefix bootloader/, \

View File

@@ -65,7 +65,7 @@ bool Boot::isKernelPatched(const Slot & s) {
return *(uint32_t *)(origin_isr + sizeof(uint32_t) * 7) == ((uint32_t)&_fake_isr_function_start) + 1;
}
__attribute((section(".fake_isr_function"))) __attribute__((used)) void Boot::flash_interrupt() {
__attribute__((section(".fake_isr_function"))) __attribute__((used)) void Boot::flash_interrupt() {
// a simple function
Ion::Device::Flash::ClearInternalFlashErrors();
asm("bx lr");

View File

@@ -47,7 +47,7 @@ public:
static void bootSlot(Bootloader::Slot slot);
static void bootSelectedSlot();
__attribute__ ((noreturn)) static void jumpToInternalBootloader();
__attribute((section(".fake_isr_function"))) __attribute__((used)) static void flash_interrupt();
__attribute__ ((section(".fake_isr_function"))) __attribute__((used)) static void flash_interrupt();
static void bootloader();
static void lockInternal();

View File

@@ -0,0 +1,46 @@
#include "upsilon_recovery.h"
#include <bootloader/slots/slot.h>
#include <bootloader/usb_data.h>
#include <ion/src/device/shared/drivers/board.h>
#include <ion.h>
#include <stdlib.h>
extern "C" void jump_to_firmware(const uint32_t* stackPtr, const void(*startPtr)(void));
Bootloader::UpsilonRecoveryMenu::UpsilonRecoveryMenu() : Menu(KDColorBlack, KDColorWhite, Messages::upsilonRecoveryTitle, Messages::mainTitle) {
setup();
}
void Bootloader::UpsilonRecoveryMenu::setup() {
m_defaultColumns[0] = Column(Messages::upsilonRecoveryMessage1, k_small_font, 0, true);
m_defaultColumns[1] = Column(Messages::upsilonRecoveryMessage2, k_small_font, 0, true);
m_defaultColumns[2] = Column(Messages::upsilonRecoveryMessage3, k_small_font, 0, true);
m_defaultColumns[3] = Column(Messages::upsilonRecoveryMessage4, k_small_font, 0, true);
m_defaultColumns[4] = Column(Messages::upsilonRecoveryMessage5, k_small_font, 0, true);
m_columns[0] = ColumnBinder(&m_defaultColumns[0]);
m_columns[1] = ColumnBinder(&m_defaultColumns[1]);
m_columns[2] = ColumnBinder(&m_defaultColumns[2]);
m_columns[3] = ColumnBinder(&m_defaultColumns[3]);
m_columns[4] = ColumnBinder(&m_defaultColumns[4]);
}
void Bootloader::UpsilonRecoveryMenu::postOpen() {
// We override the open method
for (;;) {
uint64_t scan = Ion::Keyboard::scan();
if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::Back)) {
while (Ion::Keyboard::scan() == Ion::Keyboard::State(Ion::Keyboard::Key::Back));
forceExit();
return;
} else if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::OnOff)) {
Ion::Power::standby();
return;
} else if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::OK)) {
Slot slot = Slot::Upsilon();
Ion::Device::Board::bootloaderMPU();
jump_to_firmware(slot.kernelHeader()->stackPointer(), slot.userlandHeader()->upsilonRecoveryBootFunction());
for(;;);
}
}
}

View File

@@ -0,0 +1,15 @@
#ifndef _BOOTLOADER_INTERFACE_MENUS_UPSILON_RECOVERY_H_
#define _BOOTLOADER_INTERFACE_MENUS_UPSILON_RECOVERY_H_
#include <bootloader/interface/src/menu.h>
namespace Bootloader {
class UpsilonRecoveryMenu : public Menu {
public:
UpsilonRecoveryMenu();
void setup() override;
void postOpen() override;
};
}
#endif

View File

@@ -9,10 +9,10 @@ namespace Bootloader {
class Menu {
public:
Menu() : Menu(KDColorBlack, KDColorWhite, Messages::mainTitle) { };
Menu(KDColor foreground, KDColor background, const char * title) : Menu(foreground, background, title, nullptr) {};
Menu(KDColor foreground, KDColor background, const char * title, const char * bottom) : Menu(foreground, background, title, bottom, false) {};
Menu(KDColor foreground, KDColor background, const char * title, const char * bottom, bool centerY) : Menu(foreground, background, title, bottom, centerY, k_columns_margin) {};
Menu(KDColor foreground, KDColor background, const char * title, const char * bottom, bool centerY, int margin) : m_columns(), m_defaultColumns(), m_slotColumns(), m_background(background), m_title(title), m_foreground(foreground), m_bottom(bottom), m_centerY(centerY), m_forced_exit(false), m_margin(margin) {
Menu(KDColor forground, KDColor background, const char * title) : Menu(forground, background, title, nullptr) {};
Menu(KDColor forground, KDColor background, const char * title, const char * bottom) : Menu(forground, background, title, bottom, false) {};
Menu(KDColor forground, KDColor background, const char * title, const char * bottom, bool centerY) : Menu(forground, background, title, bottom, centerY, k_columns_margin) {};
Menu(KDColor forground, KDColor background, const char * title, const char * bottom, bool centerY, int margin) : m_columns(), m_defaultColumns(), m_slotColumns(), m_background(background), m_title(title), m_foreground(forground), m_bottom(bottom), m_centerY(centerY), m_forced_exit(false), m_margin(margin) {
setup();
}
static const int k_columns_margin = 5;

View File

@@ -53,6 +53,15 @@ public:
constexpr static const char * recoveryMessage4 = "Press Back to continue.";
constexpr static const char * recoveryMessage5 = "(you will not be able to recover your data !)";
// Upsilon Recovery menu
constexpr static const char * upsilonRecoveryTitle = "Upsilon Recovery";
constexpr static const char * upsilonRecoveryMessage1 = "The bootloader has detected a crash.";
constexpr static const char * upsilonRecoveryMessage2 = "Because you also have an Upsilon slot,";
constexpr static const char * upsilonRecoveryMessage3 = "you can recover your data by booting";
constexpr static const char * upsilonRecoveryMessage4 = "the Upsilon slot.";
constexpr static const char * upsilonRecoveryMessage5 = "Press OK to continue, BACK to cancel";
// Warning menu
constexpr static const char * epsilonWarningTitle = "Epsilon Slot";

View File

@@ -1,6 +1,7 @@
#include <bootloader/recovery.h>
#include <ion.h>
#include <ion/src/device/n0110/drivers/power.h>
#include <ion/src/device/shared/drivers/bldata.h>
#include <ion/src/device/shared/drivers/reset.h>
#include <ion/src/device/shared/drivers/board.h>
#include <assert.h>
@@ -10,6 +11,7 @@
#include <bootloader/usb_data.h>
#include <bootloader/interface/menus/slot_recovery.h>
#include <bootloader/interface/menus/crash.h>
#include <bootloader/interface/menus/upsilon_recovery.h>
constexpr static uint32_t MagicStorage = 0xEE0BDDBA;
@@ -76,7 +78,15 @@ void Bootloader::Recovery::recoverData() {
Ion::Display::pushRectUniform(KDRect(0,0,320,240), KDColorWhite);
Ion::Backlight::init();
USBData udata = USBData::Recovery((uint32_t)getSlotConcerned().getStorageAddress(), (uint32_t)getSlotConcerned().getStorageSize());
CrashedSlot slot = getSlotConcerned();
if (Slot::hasUpsilon() && Slot::Upsilon().userlandHeader()->hasUpsilonExtras()) {
Ion::Device::BootloaderSharedData::sharedBootloaderData()->setRecovery((uint32_t)slot.getStorageAddress(), slot.getStorageSize());
UpsilonRecoveryMenu reco = UpsilonRecoveryMenu();
reco.open();
}
USBData udata = USBData::Recovery((uint32_t)slot.getStorageAddress(), (uint32_t)slot.getStorageSize());
SlotRecoveryMenu menu = SlotRecoveryMenu(&udata);
menu.open();

View File

@@ -2,6 +2,7 @@
#include <ion/src/device/shared/drivers/board.h>
#include <ion/src/device/shared/drivers/flash.h>
#include <bootloader/boot.h>
#include <assert.h>
extern "C" void jump_to_firmware(const uint32_t* stackPtr, const void(*startPtr)(void));
@@ -19,6 +20,15 @@ const Slot Slot::Khi() {
return Slot(0x90180000);
}
const bool Slot::hasUpsilon() {
return (isFullyValid(A()) && A().userlandHeader()->isUpsilon()) || (isFullyValid(B()) && B().userlandHeader()->isUpsilon());
}
const Slot Slot::Upsilon() {
assert(hasUpsilon());
return (isFullyValid(A()) && A().userlandHeader()->isUpsilon()) ? A() : B();
}
const KernelHeader* Slot::kernelHeader() const {
return m_kernelHeader;
}

View File

@@ -24,6 +24,8 @@ public:
static const Slot A();
static const Slot B();
static const Slot Khi();
static const bool hasUpsilon();
static const Slot Upsilon();
static bool isFullyValid(const Slot& slot) {
return slot.kernelHeader()->isValid() && slot.userlandHeader()->isValid();

View File

@@ -38,4 +38,12 @@ const size_t UserlandHeader::storageSize() const {
return m_storageSizeRAM;
}
const bool UserlandHeader::hasUpsilonExtras() const {
return m_upsilonExtraMagicFooter == UpsilonMagic;
}
const void (*UserlandHeader::upsilonRecoveryBootFunction() const)() {
return m_recoveryAddress;
}
}

View File

@@ -17,6 +17,9 @@ public:
const char * upsilonVersion() const;
const void * storageAddress() const;
const size_t storageSize() const;
const bool hasUpsilonExtras() const;
const void (*upsilonRecoveryBootFunction() const)();
private:
UserlandHeader();
@@ -42,6 +45,8 @@ private:
const char m_UpsilonVersion[16];
uint32_t m_osType;
uint32_t m_upsilonMagicFooter;
const void (*m_recoveryAddress)();
uint32_t m_upsilonExtraMagicFooter;
};
extern const UserlandHeader* s_userlandHeaderA;