diff --git a/include/arm11/main.h b/include/arm11/main.h index acf6986..42f469e 100644 --- a/include/arm11/main.h +++ b/include/arm11/main.h @@ -20,5 +20,8 @@ +// true: skip/leave menu extern volatile bool g_continueBootloader; -extern volatile bool g_startFirmLaunch; + +// 0 if no FIRM loaded / 1...3 FIRM loaded from slot / > 3 FIRM loaded from elsewhere +extern volatile u32 g_startFirmLaunch; diff --git a/include/arm11/menu/bootslot_store.h b/include/arm11/menu/bootslot_store.h new file mode 100644 index 0000000..b633d06 --- /dev/null +++ b/include/arm11/menu/bootslot_store.h @@ -0,0 +1,27 @@ +#pragma once + +/* + * This file is part of fastboot 3DS + * Copyright (C) 2017 derrek, profi200 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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 . + */ + +#include "types.h" +#include "arm11/hardware/i2c.h" + +#define BOOTSLOT_STORE_REG ((u8) 0x1E) + +#define readStoredBootslot() I2C_readReg(I2C_DEV_MCU, BOOTSLOT_STORE_REG) +#define storeBootslot(slot) I2C_writeReg(I2C_DEV_MCU, BOOTSLOT_STORE_REG, (u8) slot) diff --git a/include/arm11/menu/menu_fb3ds.h b/include/arm11/menu/menu_fb3ds.h index 6a92d41..5733c3d 100644 --- a/include/arm11/menu/menu_fb3ds.h +++ b/include/arm11/menu/menu_fb3ds.h @@ -92,7 +92,7 @@ { "Boot [slot 1]", DESC_BOOT_SLOT(1), &menuLaunchFirm, 0x00 }, { "Boot [slot 2]", DESC_BOOT_SLOT(2), &menuLaunchFirm, 0x01 }, { "Boot [slot 3]", DESC_BOOT_SLOT(3), &menuLaunchFirm, 0x02 }, - { "Boot from firm1:", DESC_BOOT_FIRM1, &menuLaunchFirm, 0xFE }, + { "Boot from FIRM1", DESC_BOOT_FIRM1, &menuLaunchFirm, 0xFE }, { "Boot setup...", DESC_BOOT_SETUP, NULL, 2 } } @@ -123,7 +123,7 @@ { "Backup NAND", DESC_NAND_BACKUP, &menuBackupNand, 0 }, { "Restore NAND", DESC_NAND_RESTORE, &menuRestoreNand, 0 }, { "Restore NAND (forced)", DESC_NAND_RESTORE_F, &menuRestoreNand, 1 }, - { "Flash firmware to firm1:", DESC_FIRM_FLASH, &menuInstallFirm, 1 } + { "Flash firmware to FIRM1", DESC_FIRM_FLASH, &menuInstallFirm, 1 } } }, { // 8 diff --git a/source/arm11/main.c b/source/arm11/main.c index 724500b..e350de9 100644 --- a/source/arm11/main.c +++ b/source/arm11/main.c @@ -20,10 +20,12 @@ #include "types.h" #include "arm11/hardware/hardware.h" #include "arm11/hardware/hid.h" +#include "arm11/menu/bootslot_store.h" #include "arm11/menu/menu.h" #include "arm11/menu/menu_fb3ds.h" #include "arm11/menu/menu_util.h" #include "arm11/menu/splash.h" +#include "arm11/bootenv.h" #include "arm11/console.h" #include "arm11/config.h" #include "arm11/debug.h" @@ -36,7 +38,7 @@ volatile bool g_continueBootloader = true; -volatile bool g_startFirmLaunch = false; +volatile u32 g_startFirmLaunch = 0; @@ -81,7 +83,7 @@ { char* path = (char*) configGetData(KBootOption1 + i); err_ptr += ee_sprintf(err_ptr, "Keys match boot slot #%lu.\nBoot path is %s\n", (i+1), path); - has_error = !(g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0)); + has_error = !(g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0) ? (i+1) : 0); err_ptr += ee_sprintf(err_ptr, "Load slot #%lu %s.\n", (i+1), g_startFirmLaunch ? "success" : "failed"); break; } @@ -95,15 +97,43 @@ } + // boot env handling (only on reboots) + u32 prevBootSlot = getBootEnv() ? readStoredBootslot() : 0; + if (!err_string && !g_startFirmLaunch && prevBootSlot) + { + err_string = (char*) malloc(512); + char* err_ptr = err_string; + if(!err_string) panicMsg("Out of memory"); + err_ptr += ee_sprintf(err_ptr, "Rebooting to boot slot #%lu...\n", prevBootSlot); + + if(!configDataExist(KBootOption1 + (prevBootSlot-1))) + { + err_ptr += ee_sprintf(err_ptr, "Could not find entry in config!\n"); + } + else + { + char* path = (char*) configGetData(KBootOption1 + (prevBootSlot-1)); + err_ptr += ee_sprintf(err_ptr, "Boot path is %s\n", path); + g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0) ? prevBootSlot : 0; + err_ptr += ee_sprintf(err_ptr, "Load slot #%lu %s.\n", prevBootSlot, g_startFirmLaunch ? "success" : "failed"); + } + + if (g_startFirmLaunch) + { + free(err_string); + err_string = NULL; + } + } + + // get bootmode from config u32 bootmode = BootModeNormal; if(configDataExist(KBootMode)) bootmode = *(u32*) configGetData(KBootMode); - // show menu if either bootmode is normal or HOME is held - // ... or not if we already got a firmware waiting in line - show_menu = show_menu || - (!g_startFirmLaunch && ((bootmode == BootModeNormal) || hidIsHomeButtonHeldRaw())); + // show menu if bootmode is normal and no firmware is waiting in line + // ... or always if the HOME button is pressed + show_menu = show_menu || (!g_startFirmLaunch && (bootmode == BootModeNormal)) || hidIsHomeButtonHeldRaw(); // show splash if (bootmode != BootModeSilent) if(show_menu || (bootmode != BootModeQuiet)) @@ -188,7 +218,7 @@ char* path = (char*) configGetData(KBootOption1 + i); err_ptr += ee_sprintf(err_ptr, "Trying boot slot #%lu.\nBoot path is %s\n", (i+1), path); - g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0); + g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0) ? (i+1) : 0; err_ptr += ee_sprintf(err_ptr, "Load slot #%lu %s.\n", (i+1), g_startFirmLaunch ? "success" : "failed"); break; } @@ -219,7 +249,11 @@ if(hidGetPowerButton(true)) power_off(); // firm launch - if(g_startFirmLaunch) firmLaunch(); + if(g_startFirmLaunch) + { + storeBootslot((g_startFirmLaunch <= 3) ? g_startFirmLaunch : 0); + firmLaunch(); + } // reaching here was never intended.... diff --git a/source/arm11/menu/menu_func.c b/source/arm11/menu/menu_func.c index 5b7289d..a820ecc 100644 --- a/source/arm11/menu/menu_func.c +++ b/source/arm11/menu/menu_func.c @@ -307,7 +307,7 @@ } ee_printf("\nFirm load success, launching firm..."); // <-- you will never see this - g_startFirmLaunch = true; + g_startFirmLaunch = (param < 3) ? (param + 1) : param; return 0;