Commit 268433e0 authored by Jamie McCrae's avatar Jamie McCrae Committed by Jamie
Browse files

zephyr: Allow user-defined boot serial extensions



This allows for out-of-tree modules to define their own boot serial
functions by using iterable sections.
Note that this also removes the custom img list command, which was
not used in-tree.

Signed-off-by: default avatarJamie McCrae <jamie.mccrae@nordicsemi.no>
parent 50f8b5f7
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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)
+0 −6
Original line number Diff line number Diff line
@@ -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"
+71 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2021-2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h>
#include <zephyr/mgmt/mcumgr/grp/zephyr/zephyr_basic.h>
#include <../subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h>

#include <flash_map_backend/flash_map_backend.h>
#include <sysflash/sysflash.h>

#include "bootutil/bootutil_log.h"
#include "../boot_serial/src/boot_serial_priv.h"
#include <zcbor_encode.h>

#include "bootutil/image.h"
#include "bootutil/bootutil_public.h"
#include "bootutil/boot_hooks.h"

#include <boot_serial/boot_serial_extensions.h>

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
+8 −139
Original line number Diff line number Diff line
/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 * Copyright (c) 2021-2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h>
#include <zephyr/mgmt/mcumgr/grp/zephyr/zephyr_basic.h>
#include <../subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h>

#include <flash_map_backend/flash_map_backend.h>
#include <sysflash/sysflash.h>

#include "bootutil/bootutil_log.h"
#include "../boot_serial/src/boot_serial_priv.h"
#include <zcbor_encode.h>

#include "bootutil/image.h"
#include "bootutil/bootutil_public.h"
#include "bootutil/boot_hooks.h"
#include <boot_serial/boot_serial_extensions.h>

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
        }
    }

+9 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/linker/iterable_sections.h>

ITERABLE_SECTION_ROM(mcuboot_bs_custom_handlers, 4)
Loading