Skip to content

Commit 832b4c9

Browse files
committed
bootutil: Add support for bootloader requests
Extend the common bootutil library to send bootloader requests instead of writing data directly into the active slot. Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent 0a425b2 commit 832b4c9

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

boot/bootutil/src/bootutil_public.c

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
#include "bootutil_priv.h"
5252
#include "bootutil_misc.h"
5353

54+
#if defined(CONFIG_BOOT_REQUEST) && !defined(CONFIG_MCUBOOT)
55+
#include <boot_request/boot_request.h>
56+
#endif /* CONFIG_BOOT_REQUEST && !CONFIG_MCUBOOT */
57+
5458
#ifdef CONFIG_MCUBOOT
5559
BOOT_LOG_MODULE_DECLARE(mcuboot);
5660
#else
@@ -503,6 +507,151 @@ boot_write_copy_done(const struct flash_area *fap)
503507
return boot_write_trailer_flag(fap, off, BOOT_FLAG_SET);
504508
}
505509

510+
#if defined(CONFIG_BOOT_REQUEST) && !defined(CONFIG_MCUBOOT)
511+
int
512+
boot_set_next(const struct flash_area *fa, bool active, bool confirm)
513+
{
514+
uint8_t i = 0;
515+
int slot_id = -1;
516+
int image_id = flash_area_get_id(fa);
517+
struct boot_swap_state slot_state;
518+
int rc;
519+
520+
BOOT_LOG_DBG("boot_set_next: fa %p active == %d, confirm == %d",
521+
fa, (int)active, (int)confirm);
522+
523+
if (active) {
524+
confirm = true;
525+
}
526+
527+
rc = boot_read_swap_state(fa, &slot_state);
528+
if (rc != 0) {
529+
return BOOT_EBADIMAGE;
530+
}
531+
532+
/* Identify image and slot number. */
533+
while (i < BOOT_IMAGE_NUMBER) {
534+
if (FLASH_AREA_IMAGE_PRIMARY(i) == image_id) {
535+
image_id = i;
536+
slot_id = 0;
537+
break;
538+
} else if (FLASH_AREA_IMAGE_SECONDARY(i) == image_id) {
539+
image_id = i;
540+
slot_id = 1;
541+
break;
542+
}
543+
544+
++i;
545+
}
546+
547+
if (slot_id == -1) {
548+
return BOOT_EBADIMAGE;
549+
}
550+
551+
/* Handle write-protected active image. */
552+
switch (slot_state.magic) {
553+
case BOOT_MAGIC_GOOD:
554+
/* fall-through */
555+
556+
case BOOT_MAGIC_UNSET:
557+
if (confirm) {
558+
BOOT_LOG_DBG("Confirm image: %d, %d", image_id, slot_id);
559+
rc = boot_request_confirm_slot(image_id, slot_id);
560+
} else {
561+
BOOT_LOG_DBG("Set image preference: %d, %d", image_id, slot_id);
562+
rc = boot_request_set_preferred_slot(image_id, slot_id);
563+
}
564+
if (rc != 0) {
565+
rc = BOOT_EBADIMAGE;
566+
}
567+
break;
568+
569+
case BOOT_MAGIC_BAD:
570+
rc = BOOT_EBADIMAGE;
571+
break;
572+
573+
default:
574+
/* Something is not OK, this should never happen */
575+
assert(0);
576+
rc = BOOT_EBADIMAGE;
577+
break;
578+
}
579+
580+
/* Handle write-enabled inactive image. */
581+
if (!active) {
582+
switch (slot_state.magic) {
583+
#ifdef MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP
584+
case BOOT_MAGIC_UNSET:
585+
rc = boot_write_magic(fa);
586+
/* fall-through */
587+
588+
case BOOT_MAGIC_GOOD:
589+
if (rc == 0 && confirm) {
590+
if (slot_state.copy_done == BOOT_FLAG_UNSET) {
591+
/* Magic is needed for DirectXIP to even try to boot application.
592+
* DirectXIP will set copy-done flag before attempting to boot
593+
* application. Next boot, application that has copy-done flag
594+
* is expected to already have ok flag, otherwise it will be removed.
595+
*/
596+
rc = boot_write_copy_done(fa);
597+
if (rc != 0) {
598+
break;
599+
}
600+
}
601+
602+
if (slot_state.image_ok == BOOT_FLAG_UNSET) {
603+
rc = boot_write_image_ok(fa);
604+
}
605+
}
606+
break;
607+
#else /* MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP */
608+
case BOOT_MAGIC_UNSET:
609+
rc = boot_write_magic(fa);
610+
611+
if (rc == 0 && confirm) {
612+
rc = boot_write_image_ok(fa);
613+
}
614+
615+
if (rc == 0) {
616+
uint8_t swap_type;
617+
618+
if (confirm) {
619+
swap_type = BOOT_SWAP_TYPE_PERM;
620+
} else {
621+
swap_type = BOOT_SWAP_TYPE_TEST;
622+
}
623+
rc = boot_write_swap_info(fa, swap_type, image_id);
624+
}
625+
break;
626+
627+
case BOOT_MAGIC_GOOD:
628+
/* If non-active then swap already scheduled, else confirm needed.*/
629+
if (slot_state.image_ok == BOOT_FLAG_UNSET) {
630+
/* Intentionally do not check copy_done flag to be able to
631+
* confirm a padded image which has been programmed using
632+
* a programming interface.
633+
*/
634+
rc = boot_write_image_ok(fa);
635+
}
636+
break;
637+
#endif /* MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP */
638+
639+
case BOOT_MAGIC_BAD:
640+
rc = BOOT_EBADVECT;
641+
break;
642+
643+
default:
644+
/* Something is not OK, this should never happen */
645+
assert(0);
646+
rc = BOOT_EBADIMAGE;
647+
break;
648+
}
649+
}
650+
651+
return rc;
652+
}
653+
#else /* CONFIG_BOOT_REQUEST && !CONFIG_MCUBOOT */
654+
506655
#ifndef MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP
507656

508657
static int flash_area_to_image(const struct flash_area *fa)
@@ -530,6 +679,9 @@ boot_set_next(const struct flash_area *fa, bool active, bool confirm)
530679
struct boot_swap_state slot_state;
531680
int rc;
532681

682+
BOOT_LOG_DBG("boot_set_next: fa %p active == %d, confirm == %d",
683+
fa, (int)active, (int)confirm);
684+
533685
if (active) {
534686
confirm = true;
535687
}
@@ -664,6 +816,7 @@ boot_set_next(const struct flash_area *fa, bool active, bool confirm)
664816
return rc;
665817
}
666818
#endif
819+
#endif /* CONFIG_BOOT_REQUEST && !CONFIG_MCUBOOT */
667820

668821
/*
669822
* This function is not used by the bootloader itself, but its required API

0 commit comments

Comments
 (0)