[bootloader] Boot other slot if a slot is invalid

This commit is contained in:
M4x1m3
2022-02-28 09:13:29 +01:00
parent 1c04949336
commit 227ca616ca
4 changed files with 38 additions and 13 deletions

View File

@@ -29,18 +29,34 @@ void Boot::setMode(BootMode mode) {
Ion::ExamMode::IncrementExamMode(deltaMode);
}
[[ noreturn ]] void Boot::boot() {
__attribute__((noreturn)) void Boot::boot() {
assert(mode() != BootMode::Unknown);
if (mode() == BootMode::SlotA)
Slot::A().boot();
else if (mode() == BootMode::SlotB)
if (!Slot::A().kernelHeader()->isValid() && !Slot::B().kernelHeader()->isValid()) {
// Bootloader if both invalid
bootloader();
} else if (!Slot::A().kernelHeader()->isValid()) {
// If slot A is invalid and B valid, boot B
setMode(BootMode::SlotB);
Slot::B().boot();
for(;;);
} else if (!Slot::B().kernelHeader()->isValid()) {
// If slot B is invalid and A valid, boot A
setMode(BootMode::SlotA);
Slot::A().boot();
} else {
// Both valid, boot the selected one
if (mode() == BootMode::SlotA) {
Slot::A().boot();
} else if (mode() == BootMode::SlotB) {
Slot::B().boot();
}
}
// Achivement unlocked: How Did We Get Here?
bootloader();
}
[[ noreturn ]] void Boot::bootloader() {
__attribute__ ((noreturn)) void Boot::bootloader() {
Bootloader::Interface::draw();
for(;;) {
Ion::USB::enable();

View File

@@ -19,8 +19,8 @@ class Boot {
public:
static BootMode mode();
static void setMode(BootMode mode);
[[ noreturn ]] static void boot();
[[ norteurn ]] static void bootloader();
__attribute__ ((noreturn)) static void boot();
__attribute__ ((noreturn)) static void bootloader();
};
}

View File

@@ -1,19 +1,20 @@
#include <ion.h>
#include <assert.h>
#include <ion/src/device/shared/drivers/board.h>
#include <bootloader/boot.h>
void ion_main(int argc, const char * const argv[]) {
__attribute__ ((noreturn)) void ion_main(int argc, const char * const argv[]) {
// Clear the screen
Ion::Display::pushRectUniform(KDRect(0,0,320,240), KDColorBlack);
// Initialize the backlight
Ion::Backlight::init();
// Set the mode to slot A if undefined
if (Bootloader::Boot::mode() == Bootloader::BootMode::Unknown)
Bootloader::Boot::setMode(Bootloader::BootMode::SlotA);
// Handle rebooting to bootloader
if (Bootloader::Boot::mode() == Bootloader::BootMode::SlotABootloader) {
Bootloader::Boot::setMode(Bootloader::BootMode::SlotA);
Bootloader::Boot::bootloader();
@@ -24,14 +25,17 @@ void ion_main(int argc, const char * const argv[]) {
uint64_t scan = Ion::Keyboard::scan();
// Reset+4 => Launch bootloader
if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::Four)) {
Bootloader::Boot::bootloader();
// Reset+1 => Launch slot A
} else if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::One)) {
Bootloader::Boot::setMode(Bootloader::BootMode::SlotA);
// Reset+2 => Launch slot B
} else if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::Two)) {
Bootloader::Boot::setMode(Bootloader::BootMode::SlotB);
}
Ion::Device::Board::bootloaderMPU();
// Boot the firmware
Bootloader::Boot::boot();
}

View File

@@ -1,4 +1,5 @@
#include <bootloader/slot.h>
#include <ion/src/device/shared/drivers/board.h>
extern "C" void jump_to_firmware(const uint32_t* stackPtr, const void(*startPtr)(void));
@@ -21,8 +22,12 @@ const UserlandHeader* Slot::userlandHeader() const {
}
[[ noreturn ]] void Slot::boot() const {
// Configure the MPU for the booted firmware
Ion::Device::Board::bootloaderMPU();
// Jump
jump_to_firmware(kernelHeader()->stackPointer(), kernelHeader()->startPointer());
for(;;);
}
}
}