From 64d264b49a072e29044fc6132113de41698152ec Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 18 May 2021 13:19:10 +0300 Subject: [PATCH] bootloader: Move chip specific things under chip specific folders - move systick.c under chip specific sources - move do_jump into chip specific main.c as arch_do_jump - wrap flash writes to "arch_flash_write" and implement in chip specific main.c - add bootloader TOC check - sync image_toc.h with the version currently in use with old bootloader Signed-off-by: Jukka Laitinen --- platforms/nuttx/src/bootloader/CMakeLists.txt | 10 +- .../src/bootloader/common/CMakeLists.txt | 46 ++++++++ .../nuttx/src/bootloader/{ => common}/bl.c | 95 +++++++++++++--- .../nuttx/src/bootloader/{ => common}/bl.h | 3 +- .../src/bootloader/{ => common}/cdcacm.h | 0 .../nuttx/src/bootloader/common/crypto.h | 68 +++++++++++ .../nuttx/src/bootloader/common/image_toc.c | 106 ++++++++++++++++++ .../{ => common}/lib/CMakeLists.txt | 1 - .../src/bootloader/{ => common}/lib/cdcacm.c | 0 .../bootloader/{ => common}/lib/flash_cache.c | 3 +- .../bootloader/{ => common}/lib/flash_cache.h | 0 .../src/bootloader/{ => common}/lib/systick.h | 0 .../src/bootloader/{ => common}/lib/uart.c | 0 .../nuttx/src/bootloader/{ => common}/uart.h | 0 .../nuttx/src/bootloader/stm/CMakeLists.txt | 35 ++++++ .../stm/stm32_common/CMakeLists.txt | 42 +++++++ .../{stm32h7 => stm/stm32_common}/main.c | 30 ++++- .../{lib => stm/stm32_common}/systick.c | 2 +- .../src/bootloader/stm/stm32h7/CMakeLists.txt | 34 ++++++ src/include/image_toc.h | 20 +++- 20 files changed, 462 insertions(+), 33 deletions(-) create mode 100644 platforms/nuttx/src/bootloader/common/CMakeLists.txt rename platforms/nuttx/src/bootloader/{ => common}/bl.c (91%) rename platforms/nuttx/src/bootloader/{ => common}/bl.h (97%) rename platforms/nuttx/src/bootloader/{ => common}/cdcacm.h (100%) create mode 100644 platforms/nuttx/src/bootloader/common/crypto.h create mode 100644 platforms/nuttx/src/bootloader/common/image_toc.c rename platforms/nuttx/src/bootloader/{ => common}/lib/CMakeLists.txt (99%) rename platforms/nuttx/src/bootloader/{ => common}/lib/cdcacm.c (100%) rename platforms/nuttx/src/bootloader/{ => common}/lib/flash_cache.c (96%) rename platforms/nuttx/src/bootloader/{ => common}/lib/flash_cache.h (100%) rename platforms/nuttx/src/bootloader/{ => common}/lib/systick.h (100%) rename platforms/nuttx/src/bootloader/{ => common}/lib/uart.c (100%) rename platforms/nuttx/src/bootloader/{ => common}/uart.h (100%) create mode 100644 platforms/nuttx/src/bootloader/stm/CMakeLists.txt create mode 100644 platforms/nuttx/src/bootloader/stm/stm32_common/CMakeLists.txt rename platforms/nuttx/src/bootloader/{stm32h7 => stm/stm32_common}/main.c (96%) rename platforms/nuttx/src/bootloader/{lib => stm/stm32_common}/systick.c (99%) create mode 100644 platforms/nuttx/src/bootloader/stm/stm32h7/CMakeLists.txt diff --git a/platforms/nuttx/src/bootloader/CMakeLists.txt b/platforms/nuttx/src/bootloader/CMakeLists.txt index ac329c7e78..558e7f3385 100644 --- a/platforms/nuttx/src/bootloader/CMakeLists.txt +++ b/platforms/nuttx/src/bootloader/CMakeLists.txt @@ -31,11 +31,7 @@ # ############################################################################ -add_library(bootloader - bl.c - ${PX4_CHIP}/main.c -) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -add_subdirectory(lib) -add_dependencies(bootloader prebuild_targets) +add_subdirectory(common) +add_subdirectory(${PX4_CHIP_MANUFACTURER}) diff --git a/platforms/nuttx/src/bootloader/common/CMakeLists.txt b/platforms/nuttx/src/bootloader/common/CMakeLists.txt new file mode 100644 index 0000000000..dce9f3a105 --- /dev/null +++ b/platforms/nuttx/src/bootloader/common/CMakeLists.txt @@ -0,0 +1,46 @@ +############################################################################ +# +# Copyright (c) 2021 Technology Innovation Institute. All rights reserved. +# +# 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 PX4 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 OWNER 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. +# +############################################################################ + +add_library(bootloader + bl.c + image_toc.c +) + +target_link_libraries(bootloader + PRIVATE + arch_bootloader +) + +add_dependencies(bootloader prebuild_targets) + +add_subdirectory(lib) diff --git a/platforms/nuttx/src/bootloader/bl.c b/platforms/nuttx/src/bootloader/common/bl.c similarity index 91% rename from platforms/nuttx/src/bootloader/bl.c rename to platforms/nuttx/src/bootloader/common/bl.c index 9d14314d61..b25941f2e5 100644 --- a/platforms/nuttx/src/bootloader/bl.c +++ b/platforms/nuttx/src/bootloader/common/bl.c @@ -43,8 +43,11 @@ #include #include #include +#include #include "bl.h" +#include "image_toc.h" +#include "crypto.h" #include "cdcacm.h" #include "uart.h" @@ -246,7 +249,7 @@ inline void cout(uint8_t *buf, unsigned len) #define arch_flash_lock flash_lock #define arch_flash_unlock flash_unlock -#define arch_setvtor(address) SCB_VTOR = address; +#define arch_setvtor(address) SCB_VTOR = (uint32_t)address; #endif @@ -283,22 +286,11 @@ buf_get(void) return ret; } -static void -do_jump(uint32_t stacktop, uint32_t entrypoint) -{ - asm volatile( - "msr msp, %0 \n" - "bx %1 \n" - : : "r"(stacktop), "r"(entrypoint) :); - - // just to keep noreturn happy - for (;;) ; -} - void jump_to_app() { const uint32_t *app_base = (const uint32_t *)APP_LOAD_ADDRESS; + const uint32_t *vec_base = (const uint32_t *)app_base; /* * We refuse to program the first word of the app until the upload is marked @@ -308,6 +300,75 @@ jump_to_app() return; } +#ifdef BOOTLOADER_USE_TOC + const image_toc_entry_t *toc_entries; + uint8_t len; + uint8_t i = 0; + + /* When secure btl is used, the address comes from the TOC */ + app_base = (const uint32_t *)0; + vec_base = (const uint32_t *)0; + + /* TOC not found or empty, stay in btl */ + if (!find_toc(&toc_entries, &len)) { + return; + } + + /* Verify the first entry, containing the TOC itself */ + if (!verify_app(0, toc_entries)) { + /* Image verification failed, stay in btl */ + return; + } + + /* TOC is verified, loop through all the apps and perform crypto ops */ + for (i = 0; i < len; i++) { + /* Verify app, if needed. i == 0 is already verified */ + if (i != 0 && + toc_entries[i].flags1 & TOC_FLAG1_CHECK_SIGNATURE && + !verify_app(i, toc_entries)) { + /* Signature check failed, don't process this app */ + continue; + } + + /* Check if this app needs decryption */ + if (toc_entries[i].flags1 & TOC_FLAG1_DECRYPT && + !decrypt_app(i, toc_entries)) { + /* Decryption / authenticated decryption failed, skip this app */ + continue; + } + + /* Check if this app needs to be copied to RAM */ + if (toc_entries[i].flags1 & TOC_FLAG1_COPY) { + /* TOC is verified, so we assume that the addresses are good */ + memcpy(toc_entries[i].target, toc_entries[i].start, + (uintptr_t)toc_entries[i].end - (uintptr_t)toc_entries[i].start); + } + + /* Check if this app is bootable, if so set the app_base */ + if (toc_entries[i].flags1 & TOC_FLAG1_BOOT) { + app_base = get_base_addr(&toc_entries[i]); + } + + /* Check if this app has vectors, if so set the vec_base */ + if (toc_entries[i].flags1 & TOC_FLAG1_VTORS) { + vec_base = get_base_addr(&toc_entries[i]); + } + } + + if (app_base == 0) { + /* No bootable app found in TOC, bail out */ + return; + } + + if (vec_base == 0) { + /* No separate vectors block, vectors come along with the app */ + vec_base = app_base; + } + +#else + + /* These checks are arm specific, and not needed when using TOC */ + /* * The second word of the app is the entrypoint; it must point within the * flash area (or we have a bad flash). @@ -320,6 +381,8 @@ jump_to_app() return; } +#endif + /* just for paranoia's sake */ arch_flash_lock(); @@ -336,10 +399,10 @@ jump_to_app() board_deinit(); /* switch exception handlers to the application */ - arch_setvtor(APP_LOAD_ADDRESS); + arch_setvtor(vec_base); - /* extract the stack and entrypoint from the app vector table and go */ - do_jump(app_base[0], app_base[1]); + /* make arch specific jump to app */ + arch_do_jump(app_base); } volatile unsigned timer[NTIMERS]; diff --git a/platforms/nuttx/src/bootloader/bl.h b/platforms/nuttx/src/bootloader/common/bl.h similarity index 97% rename from platforms/nuttx/src/bootloader/bl.h rename to platforms/nuttx/src/bootloader/common/bl.h index 7c63f73443..c4ebf588fa 100644 --- a/platforms/nuttx/src/bootloader/bl.h +++ b/platforms/nuttx/src/bootloader/common/bl.h @@ -112,7 +112,8 @@ extern uint32_t flash_func_read_otp(uint32_t address); extern uint32_t flash_func_read_sn(uint32_t address); extern void arch_flash_lock(void); extern void arch_flash_unlock(void); -extern void arch_setvtor(uint32_t address); +extern void arch_setvtor(const uint32_t *address); +extern void arch_do_jump(const uint32_t *app_base); void arch_systic_init(void); void arch_systic_deinit(void); diff --git a/platforms/nuttx/src/bootloader/cdcacm.h b/platforms/nuttx/src/bootloader/common/cdcacm.h similarity index 100% rename from platforms/nuttx/src/bootloader/cdcacm.h rename to platforms/nuttx/src/bootloader/common/cdcacm.h diff --git a/platforms/nuttx/src/bootloader/common/crypto.h b/platforms/nuttx/src/bootloader/common/crypto.h new file mode 100644 index 0000000000..cbd4d289ed --- /dev/null +++ b/platforms/nuttx/src/bootloader/common/crypto.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2019 PX4 Development Team. All rights reserved. + * + * 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 PX4 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 OWNER 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. + * + ****************************************************************************/ + +/** + * @file crypto.h + * + * Wrapper for the crypto stuff + * + */ + +#pragma once + +#ifdef BOOTLOADER_USE_TOC + +#ifdef BOOTLOADER_USE_SECURITY + +#include + +#include "hw_config.h" +#include "image_toc.h" + +bool verify_app(uint16_t idx, const image_toc_entry_t *toc_entries); + +bool decrypt_app(uint16_t idx, const image_toc_entry_t *toc_entries); + +#else + +/* No security, application verification passes always */ + +static inline bool verify_app(uint16_t idx, const image_toc_entry_t *toc_entries) {return true;} + +/* No security, decrypting is not possible */ + +static inline bool decrypt_app(uint16_t idx, const image_toc_entry_t *toc_entries) {return false;} + +#endif + +#endif diff --git a/platforms/nuttx/src/bootloader/common/image_toc.c b/platforms/nuttx/src/bootloader/common/image_toc.c new file mode 100644 index 0000000000..9b723dac60 --- /dev/null +++ b/platforms/nuttx/src/bootloader/common/image_toc.c @@ -0,0 +1,106 @@ +/**************************************************************************** + * + * Copyright (c) 2020 Technology Innovation Institute. All rights reserved. + * + * 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 PX4 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 OWNER 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 "hw_config.h" + +#ifdef BOOTLOADER_USE_TOC + +#include +#include +#include +#include + +#include "image_toc.h" + +#include "bl.h" + +/* Helper macros to define flash start and end addresses, based on info from + * hw_config.h + */ +#define FLASH_START_ADDRESS (APP_LOAD_ADDRESS & (~(BOARD_FLASH_SIZE - 1))) +#define FLASH_END_ADDRESS (FLASH_START_ADDRESS + BOARD_FLASH_SIZE) + +bool find_toc(const image_toc_entry_t **toc_entries, uint8_t *len) +{ + const uintptr_t toc_start_u32 = APP_LOAD_ADDRESS + BOOT_DELAY_ADDRESS + 8; + const image_toc_start_t *toc_start = (const image_toc_start_t *)toc_start_u32; + const image_toc_entry_t *entry = (const image_toc_entry_t *)(toc_start_u32 + sizeof(image_toc_start_t)); + + int i = 0; + uint8_t sig_idx; + const uint32_t toc_end_magic = TOC_END_MAGIC; + + if (toc_start->magic == TOC_START_MAGIC && + toc_start->version <= TOC_VERSION) { + + /* Count the entries in TOC */ + while (i < MAX_TOC_ENTRIES && + (uintptr_t)&entry[i] <= FLASH_END_ADDRESS - sizeof(uintptr_t) && + memcmp(&entry[i], &toc_end_magic, sizeof(toc_end_magic))) { + i++; + } + + /* The number of toc entries found must be within bounds, and the + * application has to lie within the flashable area. Also ensure that + * end > start. + */ + + if (i <= MAX_TOC_ENTRIES && i > 0 && + (uintptr_t)entry[0].start == APP_LOAD_ADDRESS && + (uintptr_t)entry[0].end <= (FLASH_END_ADDRESS - sizeof(uintptr_t)) && + (uintptr_t)entry[0].end > (uintptr_t)entry[0].start) { + sig_idx = entry[0].signature_idx; + + /* The signature idx for the first app must be within the TOC, and + * the signature must be within the flash area, not overlapping the + * app. Also ensure that end > start. + */ + + if (sig_idx > 0 && + sig_idx < MAX_TOC_ENTRIES && + (uintptr_t)entry[sig_idx].start >= (uintptr_t)entry[0].end && + (uintptr_t)entry[sig_idx].end <= FLASH_END_ADDRESS && + (uintptr_t)entry[sig_idx].end > (uintptr_t)entry[sig_idx].start) { + *toc_entries = entry; + *len = i; + return true; + } + } + } + + *toc_entries = NULL; + *len = 0; + return false; +} + +#endif diff --git a/platforms/nuttx/src/bootloader/lib/CMakeLists.txt b/platforms/nuttx/src/bootloader/common/lib/CMakeLists.txt similarity index 99% rename from platforms/nuttx/src/bootloader/lib/CMakeLists.txt rename to platforms/nuttx/src/bootloader/common/lib/CMakeLists.txt index ae021faa7e..f797021144 100644 --- a/platforms/nuttx/src/bootloader/lib/CMakeLists.txt +++ b/platforms/nuttx/src/bootloader/common/lib/CMakeLists.txt @@ -32,7 +32,6 @@ ############################################################################ add_library(bootloader_lib - systick.c cdcacm.c uart.c flash_cache.c diff --git a/platforms/nuttx/src/bootloader/lib/cdcacm.c b/platforms/nuttx/src/bootloader/common/lib/cdcacm.c similarity index 100% rename from platforms/nuttx/src/bootloader/lib/cdcacm.c rename to platforms/nuttx/src/bootloader/common/lib/cdcacm.c diff --git a/platforms/nuttx/src/bootloader/lib/flash_cache.c b/platforms/nuttx/src/bootloader/common/lib/flash_cache.c similarity index 96% rename from platforms/nuttx/src/bootloader/lib/flash_cache.c rename to platforms/nuttx/src/bootloader/common/lib/flash_cache.c index b84201d961..2c83bb124a 100644 --- a/platforms/nuttx/src/bootloader/lib/flash_cache.c +++ b/platforms/nuttx/src/bootloader/common/lib/flash_cache.c @@ -38,6 +38,7 @@ #include +extern ssize_t arch_flash_write(size_t address, const void *buffer, size_t buflen); flash_cache_line_t flash_cache[FC_NUMBER_LINES]; @@ -76,7 +77,7 @@ inline int fc_is_dirty(flash_cache_line_t *fl) int fc_flush(flash_cache_line_t *fl) { size_t bytes = (fl->index + 1) * sizeof(fl->words[0]); - size_t rv = up_progmem_write(fl->start_address, fl->words, bytes); + size_t rv = arch_flash_write(fl->start_address, fl->words, bytes); if (rv == bytes) { rv = 0; diff --git a/platforms/nuttx/src/bootloader/lib/flash_cache.h b/platforms/nuttx/src/bootloader/common/lib/flash_cache.h similarity index 100% rename from platforms/nuttx/src/bootloader/lib/flash_cache.h rename to platforms/nuttx/src/bootloader/common/lib/flash_cache.h diff --git a/platforms/nuttx/src/bootloader/lib/systick.h b/platforms/nuttx/src/bootloader/common/lib/systick.h similarity index 100% rename from platforms/nuttx/src/bootloader/lib/systick.h rename to platforms/nuttx/src/bootloader/common/lib/systick.h diff --git a/platforms/nuttx/src/bootloader/lib/uart.c b/platforms/nuttx/src/bootloader/common/lib/uart.c similarity index 100% rename from platforms/nuttx/src/bootloader/lib/uart.c rename to platforms/nuttx/src/bootloader/common/lib/uart.c diff --git a/platforms/nuttx/src/bootloader/uart.h b/platforms/nuttx/src/bootloader/common/uart.h similarity index 100% rename from platforms/nuttx/src/bootloader/uart.h rename to platforms/nuttx/src/bootloader/common/uart.h diff --git a/platforms/nuttx/src/bootloader/stm/CMakeLists.txt b/platforms/nuttx/src/bootloader/stm/CMakeLists.txt new file mode 100644 index 0000000000..d92823f010 --- /dev/null +++ b/platforms/nuttx/src/bootloader/stm/CMakeLists.txt @@ -0,0 +1,35 @@ +############################################################################ +# +# Copyright (c) 2021 Technology Innovation Institute. All rights reserved. +# +# 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 PX4 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 OWNER 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. +# +############################################################################ + +add_subdirectory(${PX4_CHIP}) + diff --git a/platforms/nuttx/src/bootloader/stm/stm32_common/CMakeLists.txt b/platforms/nuttx/src/bootloader/stm/stm32_common/CMakeLists.txt new file mode 100644 index 0000000000..8a35633ac2 --- /dev/null +++ b/platforms/nuttx/src/bootloader/stm/stm32_common/CMakeLists.txt @@ -0,0 +1,42 @@ +############################################################################ +# +# Copyright (c) 2021 Technology Innovation Institute. All rights reserved. +# +# 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 PX4 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 OWNER 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. +# +############################################################################ + +px4_add_library(arch_bootloader + main.c + systick.c +) + +target_link_libraries(arch_bootloader + PRIVATE + bootloader_lib +) diff --git a/platforms/nuttx/src/bootloader/stm32h7/main.c b/platforms/nuttx/src/bootloader/stm/stm32_common/main.c similarity index 96% rename from platforms/nuttx/src/bootloader/stm32h7/main.c rename to platforms/nuttx/src/bootloader/stm/stm32_common/main.c index 72221b984a..aa696831cc 100644 --- a/platforms/nuttx/src/bootloader/stm32h7/main.c +++ b/platforms/nuttx/src/bootloader/stm/stm32_common/main.c @@ -424,22 +424,27 @@ clock_deinit(void) } -inline void arch_flash_lock(void) +void arch_flash_lock(void) { stm32h7_flash_lock(STM32_FLASH_BANK1); stm32h7_flash_lock(STM32_FLASH_BANK2); } -inline void arch_flash_unlock(void) +void arch_flash_unlock(void) { fc_reset(); stm32h7_flash_unlock(STM32_FLASH_BANK1); stm32h7_flash_unlock(STM32_FLASH_BANK2); } -inline void arch_setvtor(uint32_t address) +ssize_t arch_flash_write(size_t address, const void *buffer, size_t buflen) { - putreg32(address, NVIC_VECTAB); + return up_progmem_write(address, buffer, buflen); +} + +inline void arch_setvtor(const uint32_t *address) +{ + putreg32((uint32_t)address, NVIC_VECTAB); } uint32_t @@ -611,6 +616,23 @@ led_toggle(unsigned led) # define SCB_CPACR (*((volatile uint32_t *) (((0xE000E000UL) + 0x0D00UL) + 0x088))) #endif +/* Make the actual jump to app */ +void +arch_do_jump(const uint32_t *app_base) +{ + /* extract the stack and entrypoint from the app vector table and go */ + uint32_t stacktop = app_base[0]; + uint32_t entrypoint = app_base[1]; + + asm volatile( + "msr msp, %0 \n" + "bx %1 \n" + : : "r"(stacktop), "r"(entrypoint) :); + + // just to keep noreturn happy + for (;;) ; +} + int bootloader_main(void) { diff --git a/platforms/nuttx/src/bootloader/lib/systick.c b/platforms/nuttx/src/bootloader/stm/stm32_common/systick.c similarity index 99% rename from platforms/nuttx/src/bootloader/lib/systick.c rename to platforms/nuttx/src/bootloader/stm/stm32_common/systick.c index e75dfce485..3bc2d00720 100644 --- a/platforms/nuttx/src/bootloader/lib/systick.c +++ b/platforms/nuttx/src/bootloader/stm/stm32_common/systick.c @@ -32,7 +32,7 @@ ****************************************************************************/ #include "arm_arch.h" -#include "systick.h" +#include "lib/systick.h" #include uint8_t systick_get_countflag(void) diff --git a/platforms/nuttx/src/bootloader/stm/stm32h7/CMakeLists.txt b/platforms/nuttx/src/bootloader/stm/stm32h7/CMakeLists.txt new file mode 100644 index 0000000000..4e7642951b --- /dev/null +++ b/platforms/nuttx/src/bootloader/stm/stm32h7/CMakeLists.txt @@ -0,0 +1,34 @@ +############################################################################ +# +# Copyright (c) 2021 Technology Innovation Institute. All rights reserved. +# +# 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 PX4 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 OWNER 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. +# +############################################################################ + +add_subdirectory(../stm32_common arch_bootloader) diff --git a/src/include/image_toc.h b/src/include/image_toc.h index 95966c4b95..066e4021aa 100644 --- a/src/include/image_toc.h +++ b/src/include/image_toc.h @@ -34,6 +34,11 @@ #ifndef _IMAGE_TOC_H #define _IMAGE_TOC_H +#include + +/* Max number of TOC entries */ +#define MAX_TOC_ENTRIES 32 + /* Table of contents entry flags, describing what to do with the image */ @@ -41,6 +46,7 @@ #define TOC_FLAG1_VTORS 0x2 #define TOC_FLAG1_CHECK_SIGNATURE 0x4 #define TOC_FLAG1_DECRYPT 0x8 +#define TOC_FLAG1_COPY 0x10 #define TOC_FLAG1_RDCT 0x80 @@ -54,7 +60,6 @@ #define TOC_VERSION BOARD_IMAGE_TOC_VERSION #endif - /* Markers for TOC start and end in the image */ typedef const struct __attribute__((__packed__)) image_toc_start { @@ -68,7 +73,7 @@ typedef struct __attribute__((__packed__)) image_toc_entry { unsigned char name[4]; /* Name of the section */ const void *start; /* Start address of the section in flash */ const void *end; /* End of the section */ - const void *target; /* Copy target address of the section */ + void *target; /* Copy target address of the section */ uint8_t signature_idx; /* Index to the signature in the TOC */ uint8_t signature_key; /* Key index for the signature */ uint8_t encryption_key; /* Key index for encryption */ @@ -102,4 +107,15 @@ typedef struct __attribute__((__packed__)) uint8_t signature[]; } image_cert_t; +extern bool find_toc(const image_toc_entry_t **toc_entries, uint8_t *len); + +/* If decrypt or copy flags are defined, this returns the target address. + * Otherwise, return the start address. + */ +inline static const void *get_base_addr(const image_toc_entry_t *e) +{ + return (e->flags1 & TOC_FLAG1_DECRYPT) || (e->flags1 & TOC_FLAG1_COPY) ? + e->target : e->start; +} + #endif