diff --git a/bootloader/main.c b/bootloader/main.c
index 560bb51767d54f5ce5eaaf95739249c4db986f8e..85ad2edb2098a883996c3cb9fef1a55e6be2d258 100644
--- a/bootloader/main.c
+++ b/bootloader/main.c
@@ -28,6 +28,10 @@
 
 #define PARTITION_START (0x10000000 + 64 * 1024)
 #define PARTITION_END (0x10000000 + 1024 * 1024 - 1)
+#define MSC_MAGIC 0x6E697807
+
+/* TODO: Make this address part of the linker script */
+void* API_CALL_MEM = (void*)0x20080000;
 
 DIR dir;
 FATFS FatFs;
@@ -68,6 +72,18 @@ int mount(void)
 	return 0;
 }
 
+int get_msc_flag(void)
+{
+	// We use the API call memory to store a magic value there.
+	uint32_t* flag = (uint32_t*)API_CALL_MEM;
+	if (*flag == MSC_MAGIC) {
+		*flag = 0;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
 int check_integrity(void)
 {
 	FIL file;
@@ -242,8 +258,8 @@ int main(void)
 
 	bootloader_display_init();
 
-	// If the button is pressed, we go into MSC mode.
-	if (PB_Get(3)) {
+	// If the button is pressed or a flag in memory is detected, we go into MSC mode.
+	if (PB_Get(3) || get_msc_flag()) {
 		msc();
 	}
 
diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index eb34e17b9401b02993b11a857d084f3d19202d25..1385839bc6abc3864f9eba03a58810d180a9b28b 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -242,7 +242,7 @@ API(API_SYSTEM_EXEC, int __epic_exec(char *name));
 /**
  * Reset/Restart card10
  */
-API(API_SYSTEM_RESET, void epic_system_reset(void));
+API(API_SYSTEM_RESET, void epic_system_reset(int to_bootloader));
 
 /**
  * PMIC API
diff --git a/epicardium/modules/lifecycle.c b/epicardium/modules/lifecycle.c
index 375cfef61dd9972fbb418f72659a1e30e69ef615..214fe4a7ceda62066aadbfaec2cc3b7520f20127 100644
--- a/epicardium/modules/lifecycle.c
+++ b/epicardium/modules/lifecycle.c
@@ -17,6 +17,8 @@
 
 #define PYCARDIUM_IVT (void *)0x10080000
 #define BLOCK_WAIT pdMS_TO_TICKS(1000)
+#define MSC_MAGIC 0x6E697807
+
 /*
  * Loading an empty filename into Pycardium will drop straight into the
  * interpreter.  This define is used to make it more clear when we intend
@@ -282,8 +284,12 @@ static void load_menu(bool reset)
 /*
  * Restart the firmware
  */
-void epic_system_reset(void)
+void epic_system_reset(int to_bootloader)
 {
+	// Set a flag for the bootloader.
+	uint32_t* flag = (uint32_t*)API_CALL_MEM;
+	*flag = to_bootloader ? MSC_MAGIC : 0;
+
 	card10_reset();
 }
 
diff --git a/pycardium/modules/os.c b/pycardium/modules/os.c
index 874a069322faaefaff63c493ebb10d3aa8ffb382..f858b868189870d3dd183b1bf2bd670a039e8dcd 100644
--- a/pycardium/modules/os.c
+++ b/pycardium/modules/os.c
@@ -77,14 +77,19 @@ static mp_obj_t mp_os_exec(mp_obj_t name_in)
 }
 static MP_DEFINE_CONST_FUN_OBJ_1(exec_obj, mp_os_exec);
 
-static mp_obj_t mp_os_reset(void)
+static mp_obj_t mp_os_reset(size_t n_args, const mp_obj_t *args)
 {
-	epic_system_reset();
+	int bootloader_mode = 0;
+	if (n_args == 1) {
+		bootloader_mode = mp_obj_get_int(args[0]);
+	}
+
+	epic_system_reset(bootloader_mode);
 
 	/* unreachable */
 	return mp_const_none;
 }
-static MP_DEFINE_CONST_FUN_OBJ_0(reset_obj, mp_os_reset);
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(reset_obj, 0, 1, mp_os_reset);
 
 static mp_obj_t mp_os_listdir(mp_obj_t py_path)
 {