aboutsummaryrefslogtreecommitdiff
path: root/projects/bootloader
diff options
context:
space:
mode:
Diffstat (limited to 'projects/bootloader')
-rw-r--r--projects/bootloader/Makefile18
-rw-r--r--projects/bootloader/bootloader.c77
-rw-r--r--projects/bootloader/crc32.c62
-rw-r--r--projects/bootloader/dfu.c128
-rw-r--r--projects/bootloader/log.c68
-rw-r--r--projects/bootloader/startup_stm32f429xx.S564
-rw-r--r--projects/bootloader/stm-init.c7
7 files changed, 819 insertions, 105 deletions
diff --git a/projects/bootloader/Makefile b/projects/bootloader/Makefile
index 4eef758..6c1012f 100644
--- a/projects/bootloader/Makefile
+++ b/projects/bootloader/Makefile
@@ -1,6 +1,22 @@
PROG = bootloader
-OBJS = crc32.o dfu.o
+OBJS = dfu.o log.o
+
+BOARD_OBJS = \
+ ./stm-init.o \
+ $(TOPLEVEL)/stm-fmc.o \
+ $(TOPLEVEL)/stm-uart.o \
+ $(TOPLEVEL)/spiflash_n25q128.o \
+ $(TOPLEVEL)/stm-keystore.o \
+ $(TOPLEVEL)/stm-flash.o \
+ $(TOPLEVEL)/syscalls.o \
+ $(BOARD_DIR)/system_stm32f4xx.o \
+ $(BOARD_DIR)/stm32f4xx_hal_msp.o \
+ ./startup_stm32f429xx.o \
+ $(BOARD_DIR)/stm32f4xx_it.o
+
+CFLAGS += -I$(LIBHAL_SRC)
+LIBS += $(LIBHAL_BLD)/libhal.a $(LIBTFM_BLD)/libtfm.a
all: $(PROG:=.elf)
diff --git a/projects/bootloader/bootloader.c b/projects/bootloader/bootloader.c
index ab3c1d9..6413597 100644
--- a/projects/bootloader/bootloader.c
+++ b/projects/bootloader/bootloader.c
@@ -5,6 +5,8 @@
* or jump to previously installed firmware.
*
* Copyright (c) 2016, NORDUnet A/S All rights reserved.
+ * Copyright: 2020, The Commons Conservancy Cryptech Project
+ * SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -16,9 +18,9 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * - Neither the name of the NORDUnet nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * - Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -32,11 +34,30 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+/* Ignore "deprecated" warnings in ARM-supplied CMSIS code:
+ *
+ * libraries/mbed/targets/cmsis/core_cm4.h:85:28: warning: listing the stack pointer register 'sp' in a clobber list is deprecated
+ * libraries/mbed/targets/cmsis/core_cm4.h:85:28: note: the value of the stack pointer after an 'asm' statement must be the same as it was before the statement
+ *
+ * This comes from our use of __set_MSP to set the stack pointer when
+ * switching tasks. If GCC ever decides to actually forbid this, then
+ * we'll have to figure out something else, possibly a native assembly
+ * function.
+ */
+#pragma GCC diagnostic ignored "-Wdeprecated"
+
#include "stm-init.h"
#include "stm-led.h"
#include "stm-uart.h"
+#include "stm-fmc.h"
#include "dfu.h"
+/* stub these out to avoid linker error */
+void fpgacfg_init(void) { }
+void sdram_init(void) { }
+void *hal_allocate_static_memory(const size_t size) { return 0; }
+
/* Linker symbols are strange in C. Make regular pointers for sanity. */
__IO uint32_t *dfu_control = &CRYPTECH_DFU_CONTROL;
__IO uint32_t *dfu_firmware = &CRYPTECH_FIRMWARE_START;
@@ -49,16 +70,20 @@ __IO uint32_t *dfu_code_ptr = &CRYPTECH_FIRMWARE_START + 1;
typedef void (*pFunction)(void);
-/* This is it's own function to make it more convenient to set a breakpoint at it in gdb */
-void do_early_dfu_jump(void)
+/* called from Reset_Handler */
+void check_early_dfu_jump(void)
{
- pFunction loaded_app = (pFunction) *dfu_code_ptr;
- /* Set the stack pointer to the correct one for the firmware */
- __set_MSP(*dfu_msp_ptr);
- /* Set the Vector Table Offset Register */
- SCB->VTOR = (uint32_t) dfu_firmware;
- loaded_app();
- while (1);
+ /* Check if we've just rebooted in order to jump to the firmware. */
+ if (*dfu_control == HARDWARE_EARLY_DFU_JUMP) {
+ *dfu_control = 0;
+ pFunction loaded_app = (pFunction) *dfu_code_ptr;
+ /* Set the stack pointer to the correct one for the firmware */
+ __set_MSP(*dfu_msp_ptr);
+ /* Set the Vector Table Offset Register */
+ SCB->VTOR = (uint32_t) dfu_firmware;
+ loaded_app();
+ while (1);
+ }
}
int should_dfu()
@@ -66,35 +91,31 @@ int should_dfu()
int i;
uint8_t rx = 0;
- /* While blinking the blue LED for one second, see if we receive a CR on the MGMT UART.
+ /* While blinking the blue LED for 5 seconds, see if we receive a CR on the MGMT UART.
* We've discussed also requiring one or both of the FPGA config jumpers installed
* before allowing DFU of the STM32 - that check could be done here.
*/
led_on(LED_BLUE);
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < 50; i++) {
HAL_Delay(100);
led_toggle(LED_BLUE);
- if (uart_recv_char2(STM_UART_MGMT, &rx, 0) == HAL_OK) {
+ if (uart_recv_char(&rx, 0) == HAL_OK) {
if (rx == 13) return 1;
}
}
return 0;
}
-int
-main()
+/* Sleep for specified number of seconds -- used after bad PIN. */
+void hal_sleep(const unsigned seconds) { HAL_Delay(seconds * 1000); }
+
+int main(void)
{
int status;
- /* Check if we've just rebooted in order to jump to the firmware. */
- if (*dfu_control == HARDWARE_EARLY_DFU_JUMP) {
- *dfu_control = 0;
- do_early_dfu_jump();
- }
-
stm_init();
- uart_send_string2(STM_UART_MGMT, (char *) "\r\n\r\nThis is the bootloader speaking...");
+ uart_send_string("\r\n\r\nThis is the bootloader speaking...");
if (should_dfu()) {
led_off(LED_BLUE);
@@ -104,9 +125,9 @@ main()
*/
led_off(LED_BLUE);
led_on(LED_RED);
- uart_send_string2(STM_UART_MGMT, (char *) "dfu_receive_firmware failed: ");
- uart_send_number2(STM_UART_MGMT, status, 3, 16);
- uart_send_string2(STM_UART_MGMT, (char *) "\r\n\r\nRebooting in three seconds\r\n");
+ uart_send_string("dfu_receive_firmware failed: ");
+ uart_send_hex(status, 2);
+ uart_send_string("\r\n\r\nRebooting in three seconds\r\n");
HAL_Delay(3000);
HAL_NVIC_SystemReset();
while (1) {};
@@ -118,7 +139,7 @@ main()
*/
*dfu_control = HARDWARE_EARLY_DFU_JUMP;
- uart_send_string2(STM_UART_MGMT, (char *) "loading firmware\r\n\r\n");
+ uart_send_string("loading firmware\r\n\r\n");
/* De-initialize hardware by rebooting */
HAL_NVIC_SystemReset();
diff --git a/projects/bootloader/crc32.c b/projects/bootloader/crc32.c
deleted file mode 100644
index 4d1a0bc..0000000
--- a/projects/bootloader/crc32.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Reference code from RFC1952. Not meant to be used outside test code. */
-
-#include "stm32f4xx_hal.h"
-
-
-/* Table of CRCs of all 8-bit messages. */
-unsigned long crc_table[256];
-
-/* Flag: has the table been computed? Initially false. */
-int crc_table_computed = 0;
-
-/* Make the table for a fast CRC. */
-void make_crc_table(void)
-{
- unsigned long c;
-
- int n, k;
- for (n = 0; n < 256; n++) {
- c = (unsigned long) n;
- for (k = 0; k < 8; k++) {
- if (c & 1) {
- c = 0xedb88320L ^ (c >> 1);
- } else {
- c = c >> 1;
- }
- }
- crc_table[n] = c;
- }
- crc_table_computed = 1;
-}
-
-/*
- Update a running crc with the bytes buf[0..len-1] and return
- the updated crc. The crc should be initialized to zero. Pre- and
- post-conditioning (one's complement) is performed within this
- function so it shouldn't be done by the caller. Usage example:
-
- unsigned long crc = 0L;
-
- while (read_buffer(buffer, length) != EOF) {
- crc = update_crc(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-uint32_t update_crc(uint32_t crc, uint8_t *buf, int len)
-{
- unsigned long c = crc ^ 0xffffffffL;
- int n;
-
- if (!crc_table_computed)
- make_crc_table();
- for (n = 0; n < len; n++) {
- c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
- }
- return c ^ 0xffffffffL;
-}
-
-/* Return the CRC of the bytes buf[0..len-1]. */
-unsigned long crc(unsigned char *buf, int len)
-{
- return update_crc(0L, buf, len);
-}
diff --git a/projects/bootloader/dfu.c b/projects/bootloader/dfu.c
index 231e388..83aef20 100644
--- a/projects/bootloader/dfu.c
+++ b/projects/bootloader/dfu.c
@@ -31,43 +31,132 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+/* Rename both CMSIS HAL_OK and libhal HAL_OK to disambiguate */
+#define HAL_OK CMSIS_HAL_OK
#include "dfu.h"
#include "stm-led.h"
#include "stm-uart.h"
#include "stm-flash.h"
+#undef HAL_OK
+
+#define HAL_OK LIBHAL_OK
+#include "hal.h"
+#include "hal_internal.h"
+#undef HAL_OK
#include <string.h>
-extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len);
+static int getline(char *buf, int len)
+{
+ int i;
+ uint8_t c;
+
+ for (i = 0; i < len; ++i) {
+ if (uart_recv_char(&c, HAL_MAX_DELAY) != CMSIS_HAL_OK)
+ return -1;
+ if (c == '\r') {
+ buf[i] = '\0';
+ break;
+ }
+ buf[i] = c;
+ }
+ return i;
+}
+static void uart_flush(void)
+{
+ uint8_t c;
+ while (uart_recv_char(&c, 0) == CMSIS_HAL_OK) { ; }
+}
+
+static int do_login(void)
+{
+ char username[8];
+ char pin[hal_rpc_max_pin_length];
+ hal_client_handle_t client = { -1 };
+ hal_user_t user;
+ int n;
+
+ uart_flush();
+ uart_send_string("\r\nUsername: ");
+ if (getline(username, sizeof(username)) <= 0)
+ return -1;
+ if (strcmp(username, "wheel") == 0)
+ user = HAL_USER_WHEEL;
+ else if (strcmp(username, "so") == 0)
+ user = HAL_USER_SO;
+ else if (strcmp(username, "user") == 0)
+ user = HAL_USER_NORMAL;
+ else
+ user = HAL_USER_NONE;
+
+ uart_flush();
+ uart_send_string("\r\nPassword: ");
+ if ((n = getline(pin, sizeof(pin))) <= 0)
+ return -1;
+
+ uart_flush();
+
+ hal_ks_init_read_only_pins_only();
+
+ if (hal_rpc_login(client, user, pin, n) != LIBHAL_OK) {
+ uart_send_string("\r\nAccess denied\r\n");
+ return -1;
+ }
+ return 0;
+}
int dfu_receive_firmware(void)
{
- uint32_t filesize = 0, crc = 0, my_crc = 0, counter = 0;
uint32_t offset = DFU_FIRMWARE_ADDR, n = DFU_UPLOAD_CHUNK_SIZE;
- uint32_t buf[DFU_UPLOAD_CHUNK_SIZE / 4];
+ hal_crc32_t crc = 0, my_crc = hal_crc32_init();
+ uint32_t filesize = 0, counter = 0;
+ uint8_t buf[DFU_UPLOAD_CHUNK_SIZE];
+
+ if (do_login() != 0)
+ return -1;
+
+ /* Fake the CLI */
+ uart_send_string("\r\ncryptech> ");
+ char cmd[64];
+ if (getline(cmd, sizeof(cmd)) <= 0)
+ return -1;
+ if (strcmp(cmd, "firmware upload") != 0) {
+ uart_send_string("\r\nInvalid command \"");
+ uart_send_string(cmd);
+ uart_send_string("\"\r\n");
+ return -1;
+ }
- uart_send_string2(STM_UART_MGMT, (char *) "\r\nOK, bootloader waiting for new firmware\r\n");
+ uart_send_string("OK, write size (4 bytes), data in 4096 byte chunks, CRC-32 (4 bytes)\r\n");
/* Read file size (4 bytes) */
- uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000);
+ uart_receive_bytes((void *) &filesize, sizeof(filesize), 10000);
if (filesize < 512 || filesize > DFU_FIRMWARE_END_ADDR - DFU_FIRMWARE_ADDR) {
+ uart_send_string("Invalid filesize ");
+ uart_send_integer(filesize, 1);
+ uart_send_string("\r\n");
return -1;
}
HAL_FLASH_Unlock();
+ uart_send_string("Send ");
+ uart_send_integer(filesize, 1);
+ uart_send_string(" bytes of data\r\n");
+
while (filesize) {
/* By initializing buf to the same value that erased flash has (0xff), we don't
* have to try and be smart when writing the last page of data to the memory.
*/
- memset(buf, 0xffffffff, sizeof(buf));
+ memset(buf, 0xff, sizeof(buf));
if (filesize < n) {
n = filesize;
}
- if (uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000) != HAL_OK) {
+ if (uart_receive_bytes((void *) buf, n, 10000) != CMSIS_HAL_OK) {
return -2;
}
filesize -= n;
@@ -75,23 +164,34 @@ int dfu_receive_firmware(void)
/* After reception of a chunk but before ACKing we have "all" the time in the world to
* calculate CRC and write it to flash.
*/
- my_crc = update_crc(my_crc, (uint8_t *) buf, n);
- stm_flash_write32(offset, buf, sizeof(buf) / 4);
+ my_crc = hal_crc32_update(my_crc, buf, n);
+ stm_flash_write32(offset, (uint32_t *)buf, sizeof(buf)/4);
offset += DFU_UPLOAD_CHUNK_SIZE;
/* ACK this chunk by sending the current chunk counter (4 bytes) */
counter++;
- uart_send_bytes(STM_UART_MGMT, (void *) &counter, 4);
+ uart_send_bytes((void *) &counter, 4);
led_toggle(LED_BLUE);
}
+ my_crc = hal_crc32_finalize(my_crc);
+
HAL_FLASH_Lock();
- /* The sending side will now send it's calculated CRC-32 */
- uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000);
+ uart_send_string("Send CRC-32\r\n");
+
+ /* The sending side will now send its calculated CRC-32 */
+ uart_receive_bytes((void *) &crc, sizeof(crc), 10000);
+
+ uart_send_string("CRC-32 0x");
+ uart_send_hex(crc, 1);
+ uart_send_string(", calculated CRC 0x");
+ uart_send_hex(my_crc, 1);
if (crc == my_crc) {
- uart_send_string2(STM_UART_MGMT, (char *) "\r\nSuccess\r\n");
- return 0;
+ uart_send_string("CRC checksum MATCHED\r\n");
+ return 0;
+ } else {
+ uart_send_string("CRC checksum did NOT match\r\n");
}
led_on(LED_RED);
diff --git a/projects/bootloader/log.c b/projects/bootloader/log.c
new file mode 100644
index 0000000..fbc0e73
--- /dev/null
+++ b/projects/bootloader/log.c
@@ -0,0 +1,68 @@
+/*
+ * log.c
+ * -----
+ * Implement libhal logging API on Alpha.
+ *
+ * Copyright (c) 2017, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the NORDUnet nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#define HAL_OK CMSIS_HAL_OK
+#include "stm-uart.h"
+#undef HAL_OK
+
+#define HAL_OK LIBHAL_OK
+#include "hal.h"
+#include "hal_internal.h"
+#undef HAL_OK
+
+static hal_log_level_t current_log_level;
+
+void hal_log_set_level(const hal_log_level_t level)
+{
+ current_log_level = level;
+}
+
+void hal_log(const hal_log_level_t level, const char *format, ...)
+{
+ if (level < current_log_level)
+ return;
+
+ char buffer[2048];
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(buffer, sizeof(buffer), format, ap);
+ va_end(ap);
+
+ uart_send_string(buffer);
+ uart_send_string("\r\n");
+}
diff --git a/projects/bootloader/startup_stm32f429xx.S b/projects/bootloader/startup_stm32f429xx.S
new file mode 100644
index 0000000..fc8bf34
--- /dev/null
+++ b/projects/bootloader/startup_stm32f429xx.S
@@ -0,0 +1,564 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f429xx.s
+ * @author MCD Application Team
+ * @version V2.4.1
+ * @date 09-October-2015
+ * @brief STM32F429xx Devices vector table for GCC based toolchains.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M4 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m4
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr sp, =_estack /* set stack pointer */
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+ /* Check if we've just rebooted in order to jump to the firmware. */
+ bl check_early_dfu_jump
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+
+ /* External Interrupts */
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word PVD_IRQHandler /* PVD through EXTI Line detection */
+ .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
+ .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_IRQHandler /* EXTI Line0 */
+ .word EXTI1_IRQHandler /* EXTI Line1 */
+ .word EXTI2_IRQHandler /* EXTI Line2 */
+ .word EXTI3_IRQHandler /* EXTI Line3 */
+ .word EXTI4_IRQHandler /* EXTI Line4 */
+ .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
+ .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
+ .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
+ .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
+ .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
+ .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
+ .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
+ .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
+ .word CAN1_TX_IRQHandler /* CAN1 TX */
+ .word CAN1_RX0_IRQHandler /* CAN1 RX0 */
+ .word CAN1_RX1_IRQHandler /* CAN1 RX1 */
+ .word CAN1_SCE_IRQHandler /* CAN1 SCE */
+ .word EXTI9_5_IRQHandler /* External Line[9:5]s */
+ .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
+ .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
+ .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
+ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+ .word TIM2_IRQHandler /* TIM2 */
+ .word TIM3_IRQHandler /* TIM3 */
+ .word TIM4_IRQHandler /* TIM4 */
+ .word I2C1_EV_IRQHandler /* I2C1 Event */
+ .word I2C1_ER_IRQHandler /* I2C1 Error */
+ .word I2C2_EV_IRQHandler /* I2C2 Event */
+ .word I2C2_ER_IRQHandler /* I2C2 Error */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word SPI2_IRQHandler /* SPI2 */
+ .word USART1_IRQHandler /* USART1 */
+ .word USART2_IRQHandler /* USART2 */
+ .word USART3_IRQHandler /* USART3 */
+ .word EXTI15_10_IRQHandler /* External Line[15:10]s */
+ .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
+ .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
+ .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
+ .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
+ .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
+ .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
+ .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
+ .word FMC_IRQHandler /* FMC */
+ .word SDIO_IRQHandler /* SDIO */
+ .word TIM5_IRQHandler /* TIM5 */
+ .word SPI3_IRQHandler /* SPI3 */
+ .word UART4_IRQHandler /* UART4 */
+ .word UART5_IRQHandler /* UART5 */
+ .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
+ .word TIM7_IRQHandler /* TIM7 */
+ .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
+ .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
+ .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
+ .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
+ .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
+ .word ETH_IRQHandler /* Ethernet */
+ .word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */
+ .word CAN2_TX_IRQHandler /* CAN2 TX */
+ .word CAN2_RX0_IRQHandler /* CAN2 RX0 */
+ .word CAN2_RX1_IRQHandler /* CAN2 RX1 */
+ .word CAN2_SCE_IRQHandler /* CAN2 SCE */
+ .word OTG_FS_IRQHandler /* USB OTG FS */
+ .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
+ .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
+ .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
+ .word USART6_IRQHandler /* USART6 */
+ .word I2C3_EV_IRQHandler /* I2C3 event */
+ .word I2C3_ER_IRQHandler /* I2C3 error */
+ .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
+ .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
+ .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
+ .word OTG_HS_IRQHandler /* USB OTG HS */
+ .word DCMI_IRQHandler /* DCMI */
+ .word 0 /* Reserved */
+ .word HASH_RNG_IRQHandler /* Hash and Rng */
+ .word FPU_IRQHandler /* FPU */
+ .word UART7_IRQHandler /* UART7 */
+ .word UART8_IRQHandler /* UART8 */
+ .word SPI4_IRQHandler /* SPI4 */
+ .word SPI5_IRQHandler /* SPI5 */
+ .word SPI6_IRQHandler /* SPI6 */
+ .word SAI1_IRQHandler /* SAI1 */
+ .word LTDC_IRQHandler /* LTDC_IRQHandler */
+ .word LTDC_ER_IRQHandler /* LTDC_ER_IRQHandler */
+ .word DMA2D_IRQHandler /* DMA2D */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMP_STAMP_IRQHandler
+ .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+ .weak RTC_WKUP_IRQHandler
+ .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream0_IRQHandler
+ .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream1_IRQHandler
+ .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream2_IRQHandler
+ .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream3_IRQHandler
+ .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream4_IRQHandler
+ .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream5_IRQHandler
+ .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream6_IRQHandler
+ .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+ .weak ADC_IRQHandler
+ .thumb_set ADC_IRQHandler,Default_Handler
+
+ .weak CAN1_TX_IRQHandler
+ .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+ .weak CAN1_RX0_IRQHandler
+ .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM9_IRQHandler
+ .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM10_IRQHandler
+ .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM11_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak TIM8_BRK_TIM12_IRQHandler
+ .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+ .weak TIM8_UP_TIM13_IRQHandler
+ .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+ .weak TIM8_TRG_COM_TIM14_IRQHandler
+ .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+ .weak TIM8_CC_IRQHandler
+ .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream7_IRQHandler
+ .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+ .weak FMC_IRQHandler
+ .thumb_set FMC_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_DAC_IRQHandler
+ .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream0_IRQHandler
+ .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream1_IRQHandler
+ .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream2_IRQHandler
+ .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream3_IRQHandler
+ .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream4_IRQHandler
+ .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+ .weak ETH_IRQHandler
+ .thumb_set ETH_IRQHandler,Default_Handler
+
+ .weak ETH_WKUP_IRQHandler
+ .thumb_set ETH_WKUP_IRQHandler,Default_Handler
+
+ .weak CAN2_TX_IRQHandler
+ .thumb_set CAN2_TX_IRQHandler,Default_Handler
+
+ .weak CAN2_RX0_IRQHandler
+ .thumb_set CAN2_RX0_IRQHandler,Default_Handler
+
+ .weak CAN2_RX1_IRQHandler
+ .thumb_set CAN2_RX1_IRQHandler,Default_Handler
+
+ .weak CAN2_SCE_IRQHandler
+ .thumb_set CAN2_SCE_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream5_IRQHandler
+ .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream6_IRQHandler
+ .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream7_IRQHandler
+ .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+ .weak USART6_IRQHandler
+ .thumb_set USART6_IRQHandler,Default_Handler
+
+ .weak I2C3_EV_IRQHandler
+ .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+ .weak I2C3_ER_IRQHandler
+ .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+ .weak OTG_HS_EP1_OUT_IRQHandler
+ .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
+
+ .weak OTG_HS_EP1_IN_IRQHandler
+ .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
+
+ .weak OTG_HS_WKUP_IRQHandler
+ .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
+
+ .weak OTG_HS_IRQHandler
+ .thumb_set OTG_HS_IRQHandler,Default_Handler
+
+ .weak DCMI_IRQHandler
+ .thumb_set DCMI_IRQHandler,Default_Handler
+
+ .weak HASH_RNG_IRQHandler
+ .thumb_set HASH_RNG_IRQHandler,Default_Handler
+
+ .weak FPU_IRQHandler
+ .thumb_set FPU_IRQHandler,Default_Handler
+
+ .weak UART7_IRQHandler
+ .thumb_set UART7_IRQHandler,Default_Handler
+
+ .weak UART8_IRQHandler
+ .thumb_set UART8_IRQHandler,Default_Handler
+
+ .weak SPI4_IRQHandler
+ .thumb_set SPI4_IRQHandler,Default_Handler
+
+ .weak SPI5_IRQHandler
+ .thumb_set SPI5_IRQHandler,Default_Handler
+
+ .weak SPI6_IRQHandler
+ .thumb_set SPI6_IRQHandler,Default_Handler
+
+ .weak SAI1_IRQHandler
+ .thumb_set SAI1_IRQHandler,Default_Handler
+
+ .weak LTDC_IRQHandler
+ .thumb_set LTDC_IRQHandler,Default_Handler
+
+ .weak LTDC_ER_IRQHandler
+ .thumb_set LTDC_ER_IRQHandler,Default_Handler
+
+ .weak DMA2D_IRQHandler
+ .thumb_set DMA2D_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/projects/bootloader/stm-init.c b/projects/bootloader/stm-init.c
new file mode 100644
index 0000000..b331b8a
--- /dev/null
+++ b/projects/bootloader/stm-init.c
@@ -0,0 +1,7 @@
+/* Disable modules that the bootloader doesn't need. */
+
+#include "stm32f4xx_hal.h"
+
+#undef HAL_I2C_MODULE_ENABLED
+
+#include "../../stm-init.c"