--- /dev/null
+diff --git a/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s b/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s
+index 38b4513..12a3f39 100644
+--- a/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s
++++ b/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s
+@@ -98,6 +98,13 @@
+ #define CRT0_CALL_DESTRUCTORS TRUE\r
+ #endif\r
+ \r
++/**\r
++ * @brief Magic number for jumping to bootloader.\r
++ */\r
++#if !defined(MAGIC_BOOTLOADER_NUMBER) || defined(__DOXYGEN__)\r
++#define MAGIC_BOOTLOADER_NUMBER 0xDEADBEEF\r
++#endif\r
++\r
+ /*===========================================================================*/\r
+ /* Code section. */\r
+ /*===========================================================================*/\r
+@@ -117,6 +124,17 @@
+ .thumb_func\r
+ .global Reset_Handler\r
+ Reset_Handler:\r
++\r
++#ifdef BOOTLOADER_ADDRESS\r
++ /* jump to bootloader code */\r
++ ldr r0, =__ram0_end__-4\r
++ ldr r1, =MAGIC_BOOTLOADER_NUMBER\r
++ ldr r2, [r0, #0]\r
++ str r0, [r0, #0] /* erase stored magic */\r
++ cmp r2, r1\r
++ beq Bootloader_Jump\r
++#endif /* BOOTLOADER_ADDRESS */\r
++\r
+ /* Interrupts are globally masked initially.*/\r
+ cpsid i\r
+ \r
+@@ -230,6 +248,21 @@ endfiniloop:
+ ldr r1, =__default_exit\r
+ bx r1\r
+ \r
++#ifdef BOOTLOADER_ADDRESS\r
++/*\r
++ * Jump-to-bootloader function.\r
++ */\r
++\r
++ .align 2\r
++ .thumb_func\r
++Bootloader_Jump:\r
++ ldr r0, =BOOTLOADER_ADDRESS\r
++ ldr r1, [r0, #0]\r
++ mov sp, r1\r
++ ldr r0, [r0, #4]\r
++ bx r0\r
++#endif /* BOOTLOADER_ADDRESS */\r
++\r
+ #endif\r
+ \r
+ /** @} */\r
+diff --git a/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s b/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
+index fcfa4de..2d560da 100644
+--- a/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
++++ b/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
+@@ -133,6 +133,13 @@
+ #define CRT0_CPACR_INIT 0x00F00000\r
+ #endif\r
+ \r
++/**\r
++ * @brief Magic number for jumping to bootloader.\r
++ */\r
++#if !defined(MAGIC_BOOTLOADER_NUMBER) || defined(__DOXYGEN__)\r
++#define MAGIC_BOOTLOADER_NUMBER 0xDEADBEEF\r
++#endif\r
++\r
+ /*===========================================================================*/\r
+ /* Code section. */\r
+ /*===========================================================================*/\r
+@@ -157,6 +164,16 @@
+ .thumb_func\r
+ .global Reset_Handler\r
+ Reset_Handler:\r
++#ifdef BOOTLOADER_ADDRESS\r
++ /* jump to bootloader code */\r
++ ldr r0, =__ram0_end__-4\r
++ ldr r1, =MAGIC_BOOTLOADER_NUMBER\r
++ ldr r2, [r0, #0]\r
++ str r0, [r0, #0] /* erase stored magic */\r
++ cmp r2, r1\r
++ beq Bootloader_Jump\r
++#endif /* BOOTLOADER_ADDRESS */\r
++\r
+ /* Interrupts are globally masked initially.*/\r
+ cpsid i\r
+ \r
+@@ -289,6 +306,21 @@ endfiniloop:
+ /* Branching to the defined exit handler.*/\r
+ b __default_exit\r
+ \r
++#ifdef BOOTLOADER_ADDRESS\r
++/*\r
++ * Jump-to-bootloader function.\r
++ */\r
++\r
++ .align 2\r
++ .thumb_func\r
++Bootloader_Jump:\r
++ ldr r0, =BOOTLOADER_ADDRESS\r
++ ldr r1, [r0, #0]\r
++ mov sp, r1\r
++ ldr r0, [r0, #4]\r
++ bx r0\r
++#endif /* BOOTLOADER_ADDRESS */\r
++\r
+ #endif /* !defined(__DOXYGEN__) */\r
+ \r
+ /** @} */\r