Skip to content

Commit

Permalink
mynewt: Add single_loader support
Browse files Browse the repository at this point in the history
There is existing functionality for Zephyr where mcuboot works
with single slot (no swap) and image can be updated via boot_serial.

To have same functionality in mynewet single_loader.c file is copied
from zephyr tree and 2 pkg.yml files are modified to utilize new
file when BOOTUTIL_SINGLE_APPLICATION_SLOT is defined

Signed-off-by: Jerzy Kasenberg <jerzy.kasenberg@codecoup.pl>
  • Loading branch information
kasjer authored and utzig committed Apr 14, 2024
1 parent 23d4f12 commit ed6460b
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 0 deletions.
3 changes: 3 additions & 0 deletions boot/bootutil/pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pkg.deps:
- "@apache-mynewt-core/sys/defs"
- "@mcuboot/boot/mynewt/flash_map_backend"

pkg.ign_files.BOOTUTIL_SINGLE_APPLICATION_SLOT:
- "loader.c"

pkg.deps.BOOTUTIL_USE_MBED_TLS:
- "@apache-mynewt-core/crypto/mbedtls"

Expand Down
3 changes: 3 additions & 0 deletions boot/mynewt/pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/log/stub"

pkg.ign_files.!BOOTUTIL_SINGLE_APPLICATION_SLOT:
- "single_loader.c"

pkg.deps.BOOTUTIL_NO_LOGGING:
- "@apache-mynewt-core/sys/console/stub"

Expand Down
136 changes: 136 additions & 0 deletions boot/mynewt/src/single_loader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2020 Nordic Semiconductor ASA
* Copyright (c) 2020 Arm Limited
*/

#include <assert.h>
#include "bootutil/image.h"
#include "../../../bootutil/src/bootutil_priv.h"
#include "bootutil/bootutil_log.h"
#include "bootutil/bootutil_public.h"
#include "bootutil/fault_injection_hardening.h"

#include "mcuboot_config/mcuboot_config.h"

BOOT_LOG_MODULE_DECLARE(mcuboot);

/* Variables passed outside of unit via poiters. */
static const struct flash_area *_fa_p;
static struct image_header _hdr = { 0 };

#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT) || defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
/**
* Validate hash of a primary boot image.
*
* @param[in] fa_p flash area pointer
* @param[in] hdr boot image header pointer
*
* @return FIH_SUCCESS on success, error code otherwise
*/
fih_ret
boot_image_validate(const struct flash_area *fa_p,
struct image_header *hdr)
{
static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
FIH_DECLARE(fih_rc, FIH_FAILURE);

/* NOTE: The first argument to boot_image_validate, for enc_state pointer,
* is allowed to be NULL only because the single image loader compiles
* with BOOT_IMAGE_NUMBER == 1, which excludes the code that uses
* the pointer from compilation.
*/
/* Validate hash */
if (IS_ENCRYPTED(hdr))
{
/* Clear the encrypted flag we didn't supply a key
* This flag could be set if there was a decryption in place
* was performed. We will try to validate the image, and if still
* encrypted the validation will fail, and go in panic mode
*/
hdr->ih_flags &= ~(ENCRYPTIONFLAGS);
}
FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, hdr, fa_p, tmpbuf,
BOOT_TMPBUF_SZ, NULL, 0, NULL);

FIH_RET(fih_rc);
}
#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT || MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE*/

#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
inline static fih_ret
boot_image_validate_once(const struct flash_area *fa_p,
struct image_header *hdr)
{
static struct boot_swap_state state;
int rc;
FIH_DECLARE(fih_rc, FIH_FAILURE);

memset(&state, 0, sizeof(struct boot_swap_state));
rc = boot_read_swap_state(fa_p, &state);
if (rc != 0)
FIH_RET(FIH_FAILURE);
if (state.magic != BOOT_MAGIC_GOOD
|| state.image_ok != BOOT_FLAG_SET) {
/* At least validate the image once */
FIH_CALL(boot_image_validate, fih_rc, fa_p, hdr);
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
FIH_RET(FIH_FAILURE);
}
if (state.magic != BOOT_MAGIC_GOOD) {
rc = boot_write_magic(fa_p);
if (rc != 0)
FIH_RET(FIH_FAILURE);
}
rc = boot_write_image_ok(fa_p);
if (rc != 0)
FIH_RET(FIH_FAILURE);
}
FIH_RET(FIH_SUCCESS);
}
#endif

/**
* Gather information on image and prepare for booting.
*
* @parami[out] rsp Parameters for booting image, on success
*
* @return FIH_SUCCESS on success; nonzero on failure.
*/
fih_ret
boot_go(struct boot_rsp *rsp)
{
int rc = -1;
FIH_DECLARE(fih_rc, FIH_FAILURE);

rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &_fa_p);
assert(rc == 0);

rc = boot_image_load_header(_fa_p, &_hdr);
if (rc != 0)
goto out;

#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
FIH_CALL(boot_image_validate, fih_rc, _fa_p, &_hdr);
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
goto out;
}
#elif defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
FIH_CALL(boot_image_validate_once, fih_rc, _fa_p, &_hdr);
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
goto out;
}
#else
fih_rc = FIH_SUCCESS;
#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */

rsp->br_flash_dev_id = flash_area_get_device_id(_fa_p);
rsp->br_image_off = flash_area_get_off(_fa_p);
rsp->br_hdr = &_hdr;

out:
flash_area_close(_fa_p);

FIH_RET(fih_rc);
}

0 comments on commit ed6460b

Please sign in to comment.