diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index d15977e77..67dfb25aa 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -85,6 +85,17 @@ if(DEFINED CONFIG_ENABLE_MGMT_PERUSER) zephyr_library_sources( boot_serial_extensions.c ) + + zephyr_linker_sources_ifdef( + CONFIG_ENABLE_MGMT_PERUSER + SECTIONS include/boot_serial/boot_serial.ld + ) + + if(DEFINED CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE OR DEFINED CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST) + zephyr_library_sources( + boot_serial_extension_zephyr_basic.c + ) + endif() endif() if(NOT DEFINED CONFIG_FLASH_PAGE_LAYOUT) diff --git a/boot/zephyr/Kconfig.serial_recovery b/boot/zephyr/Kconfig.serial_recovery index 52ec3b013..c73baddf0 100644 --- a/boot/zephyr/Kconfig.serial_recovery +++ b/boot/zephyr/Kconfig.serial_recovery @@ -128,12 +128,6 @@ config BOOT_MGMT_CUSTOM_STORAGE_ERASE Note that the storage partition needs to be defined, in DTS, otherwise enabling the option will cause a compilation to fail. -config BOOT_MGMT_CUSTOM_IMG_LIST - bool "Enable custom image list command" - help - The option enables command which returns versions and installation - statuses (custom property) for all images. - endif # ENABLE_MGMT_PERUSER menu "Entrance methods" diff --git a/boot/zephyr/boot_serial_extension_zephyr_basic.c b/boot/zephyr/boot_serial_extension_zephyr_basic.c new file mode 100644 index 000000000..b0c75f4a7 --- /dev/null +++ b/boot/zephyr/boot_serial_extension_zephyr_basic.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021-2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include <../subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h> + +#include +#include + +#include "bootutil/bootutil_log.h" +#include "../boot_serial/src/boot_serial_priv.h" +#include + +#include "bootutil/image.h" +#include "bootutil/bootutil_public.h" +#include "bootutil/boot_hooks.h" + +#include + +BOOT_LOG_MODULE_DECLARE(mcuboot); + +#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE +static int bs_custom_storage_erase(const struct nmgr_hdr *hdr, + const char *buffer, int len, + zcbor_state_t *cs) +{ + int rc; + const struct flash_area *fa; + + (void)buffer; + (void)len; + + if (hdr->nh_group != ZEPHYR_MGMT_GRP_BASIC || hdr->nh_op != NMGR_OP_WRITE || + hdr->nh_id != ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) { + return MGMT_ERR_ENOTSUP; + } + + rc = flash_area_open(FIXED_PARTITION_ID(storage_partition), &fa); + + if (rc < 0) { + BOOT_LOG_ERR("failed to open flash area"); + } else { + rc = flash_area_erase(fa, 0, flash_area_get_size(fa)); + if (rc < 0) { + BOOT_LOG_ERR("failed to erase flash area"); + } + flash_area_close(fa); + } + if (rc == 0) { + rc = MGMT_ERR_OK; + } else { + rc = MGMT_ERR_EUNKNOWN; + } + + zcbor_map_start_encode(cs, 10); + zcbor_tstr_put_lit(cs, "rc"); + zcbor_uint32_put(cs, rc); + zcbor_map_end_encode(cs, 10); + + return rc; +} + +MCUMGR_HANDLER_DEFINE(storage_erase, bs_custom_storage_erase); +#endif diff --git a/boot/zephyr/boot_serial_extensions.c b/boot/zephyr/boot_serial_extensions.c index b8bcd3e95..abbb65173 100644 --- a/boot/zephyr/boot_serial_extensions.c +++ b/boot/zephyr/boot_serial_extensions.c @@ -1,161 +1,30 @@ /* - * Copyright (c) 2021 Nordic Semiconductor ASA + * Copyright (c) 2021-2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ -#include #include -#include -#include -#include -#include <../subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h> - -#include -#include #include "bootutil/bootutil_log.h" #include "../boot_serial/src/boot_serial_priv.h" #include - -#include "bootutil/image.h" -#include "bootutil/bootutil_public.h" -#include "bootutil/boot_hooks.h" +#include BOOT_LOG_MODULE_DECLARE(mcuboot); -#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE -static int bs_custom_storage_erase(zcbor_state_t *cs) -{ - int rc; - - const struct flash_area *fa; - - rc = flash_area_open(FIXED_PARTITION_ID(storage_partition), &fa); - - if (rc < 0) { - BOOT_LOG_ERR("failed to open flash area"); - } else { - rc = flash_area_erase(fa, 0, flash_area_get_size(fa)); - if (rc < 0) { - BOOT_LOG_ERR("failed to erase flash area"); - } - flash_area_close(fa); - } - if (rc == 0) { - rc = MGMT_ERR_OK; - } else { - rc = MGMT_ERR_EUNKNOWN; - } - - zcbor_map_start_encode(cs, 10); - zcbor_tstr_put_lit(cs, "rc"); - zcbor_uint32_put(cs, rc); - zcbor_map_end_encode(cs, 10); - - return rc; -} -#endif - -#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST -static int custom_img_status(int image_index, uint32_t slot,char *buffer, - ssize_t len) -{ - uint32_t area_id; - struct flash_area const *fap; - struct image_header hdr; - int rc; - int img_install_stat; - - rc = BOOT_HOOK_CALL(boot_img_install_stat_hook, BOOT_HOOK_REGULAR, - image_index, slot, &img_install_stat); - if (rc == BOOT_HOOK_REGULAR) - { - img_install_stat = 0; - } - - rc = BOOT_HOOK_CALL(boot_read_image_header_hook, BOOT_HOOK_REGULAR, - image_index, slot, &hdr); - if (rc == BOOT_HOOK_REGULAR) - { - area_id = flash_area_id_from_multi_image_slot(image_index, slot); - - rc = flash_area_open(area_id, &fap); - if (rc) { - return rc; - } - - rc = flash_area_read(fap, 0, &hdr, sizeof(hdr)); - - flash_area_close(fap); - } - - if (rc == 0) { - if (hdr.ih_magic == IMAGE_MAGIC) { - snprintf(buffer, len, "ver=%d.%d.%d.%d,install_stat=%d", - hdr.ih_ver.iv_major, - hdr.ih_ver.iv_minor, - hdr.ih_ver.iv_revision, - hdr.ih_ver.iv_build_num, - img_install_stat); - } else { - rc = 1; - } - } - - return rc; -} - -static int bs_custom_img_list(zcbor_state_t *cs) -{ - int rc = 0; - char tmpbuf[64]; /* Buffer should fit version and flags */ - - zcbor_map_start_encode(cs, 10); - - for (int img = 0; img < MCUBOOT_IMAGE_NUMBER; img++) { - for (int slot = 0; slot < 2; slot++) { - rc = custom_img_status(img, slot, tmpbuf, sizeof(tmpbuf)); - - zcbor_int32_put(cs, img * 2 + slot + 1); - if (rc == 0) { - zcbor_tstr_put_term(cs, tmpbuf); - } else { - zcbor_tstr_put_lit(cs, ""); - } - } - } - - zcbor_tstr_put_lit(cs, "rc"); - zcbor_uint32_put(cs, MGMT_ERR_OK); - zcbor_map_end_encode(cs, 10); - - return rc; -} - -#ifndef ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST - #define ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST 1 -#endif -#endif /*MCUBOOT_MGMT_CUSTOM_IMG_LIST*/ - int bs_peruser_system_specific(const struct nmgr_hdr *hdr, const char *buffer, int len, zcbor_state_t *cs) { int mgmt_rc = MGMT_ERR_ENOTSUP; - if (hdr->nh_group == ZEPHYR_MGMT_GRP_BASIC) { - if (hdr->nh_op == NMGR_OP_WRITE) { -#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE - if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) { - mgmt_rc = bs_custom_storage_erase(cs); - } -#endif - } else if (hdr->nh_op == NMGR_OP_READ) { -#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST - if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST) { - mgmt_rc = bs_custom_img_list(cs); + STRUCT_SECTION_FOREACH(mcuboot_bs_custom_handlers, function) { + if (function->handler) { + mgmt_rc = function->handler(hdr, buffer, len, cs); + + if (mgmt_rc != MGMT_ERR_ENOTSUP) { + break; } -#endif } } diff --git a/boot/zephyr/include/boot_serial/boot_serial.ld b/boot/zephyr/include/boot_serial/boot_serial.ld new file mode 100644 index 000000000..c0e82ad35 --- /dev/null +++ b/boot/zephyr/include/boot_serial/boot_serial.ld @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +ITERABLE_SECTION_ROM(mcuboot_bs_custom_handlers, 4) diff --git a/boot/zephyr/include/boot_serial/boot_serial_extensions.h b/boot/zephyr/include/boot_serial/boot_serial_extensions.h new file mode 100644 index 000000000..6eea574fa --- /dev/null +++ b/boot/zephyr/include/boot_serial/boot_serial_extensions.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_BOOT_SERIAL_EXTENTIONS_ +#define H_BOOT_SERIAL_EXTENTIONS_ + +#include +#include +#include + +/** + * Callback handler prototype for boot serial extensions. + * + * @param[in] hdr MCUmgr header + * @param[in] buffer Buffer with first MCUmgr message + * @param[in] len Length of data in buffer + * @param[out] cs Response + * + * @return MGMT_ERR_ENOTSUP to run other handlers, other MGMT_ERR_* value + * when expected handler has ran. + */ +typedef int (*bs_custom_handler_cb)(const struct nmgr_hdr *hdr, + const char *buffer, int len, + zcbor_state_t *cs); + +struct mcuboot_bs_custom_handlers { + const bs_custom_handler_cb handler; +}; + +/* Used to create an iterable section containing a boot serial handler + * function + */ +#define MCUMGR_HANDLER_DEFINE(name, _handler) \ + STRUCT_SECTION_ITERABLE(mcuboot_bs_custom_handlers, name) = { \ + .handler = _handler, \ + } + +#endif /* H_BOOT_SERIAL_EXTENTIONS_ */ diff --git a/docs/release-notes.d/zephyr-bs-extensions.md b/docs/release-notes.d/zephyr-bs-extensions.md new file mode 100644 index 000000000..0cc748367 --- /dev/null +++ b/docs/release-notes.d/zephyr-bs-extensions.md @@ -0,0 +1,3 @@ +- Reworked boot serial extensions so that they can be used by modules + or from user repositories by switching to iterable sections. +- Removed Zephyr custom img list boot serial extension support.