The single-slot (MCUBOOT_SINGLE_APPLICATION_SLOT) boot path exists twice, in two
ports, and not at all in the shared library:
| File |
Lines |
boot/zephyr/single_loader.c |
255 |
boot/mynewt/src/single_loader.c |
136 |
boot/bootutil/src/ |
— none |
Both provide boot_go() plus a local boot_image_validate(); Zephyr's
additionally provides boot_get_loader_state(), boot_get_image_max_sizes(),
boot_open_all_flash_areas(), boot_close_all_flash_areas() and
app_max_size(), of which the first four are only referenced by
boot_fetch_slot_state_sizes() in bootutil_misc.c, inside
#if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO).
Neither implementation appears to depend on its host OS. In
boot/zephyr/single_loader.c I could find no Zephyr API call, no CONFIG_*
reference and no devicetree use; its includes are assert.h, bootutil/*,
bootutil_priv.h and mcuboot_config/mcuboot_config.h, and the only
non-bootutil symbols it references are the BOOT_LOG_* macros, which are
already part of the port configuration contract. The same appears to hold for
the Mynewt version.
Why it matters
boot_go() has two implementations — the multi-slot state machine in
boot/bootutil/src/loader.c, and the single-slot path — and the build system
selects between them (boot/zephyr/CMakeLists.txt, the
CONFIG_SINGLE_APPLICATION_SLOT branch). Because only the multi-slot
implementation lives in the shared library, an out-of-tree port that wants
single-slot support has to write the second one itself, even though it is
almost entirely calls into bootutil.
That also means the two in-tree copies can drift from each other and from
bootutil, and each has to be updated separately when the bootutil interface
changes.
Proposal
Move the OS-independent part of the single-slot boot path into
boot/bootutil/src/single_loader.c and have the Zephyr and Mynewt ports use it,
leaving anything genuinely port-specific behind. This would be a
behaviour-preserving refactor rather than a feature change, and would give
out-of-tree ports the same choice of boot_go() implementation that the in-tree
ports have.
Questions before attempting a PR
- Is consolidating these two into
bootutil a direction you would accept in
principle, or is the duplication deliberate?
sim/Cargo.toml has features for overwrite-only, swap-move,
swap-offset and so on, but none for single-slot, so as far as I can tell the
single-slot path currently has no simulator coverage. For a
behaviour-preserving move, would you want simulator coverage for single-slot
added first (or as part of the same PR), or is the absence of coverage
acceptable for a relocation?
- If you would take it, do you have a preference on scope — move Zephyr's
version and have Mynewt adopt it, or reduce to the smaller common subset and
let each port keep what only it needs?
Happy to do the work if the direction is welcome; asking first per
docs/contributing.md.
The single-slot (
MCUBOOT_SINGLE_APPLICATION_SLOT) boot path exists twice, in twoports, and not at all in the shared library:
boot/zephyr/single_loader.cboot/mynewt/src/single_loader.cboot/bootutil/src/Both provide
boot_go()plus a localboot_image_validate(); Zephyr'sadditionally provides
boot_get_loader_state(),boot_get_image_max_sizes(),boot_open_all_flash_areas(),boot_close_all_flash_areas()andapp_max_size(), of which the first four are only referenced byboot_fetch_slot_state_sizes()inbootutil_misc.c, inside#if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO).Neither implementation appears to depend on its host OS. In
boot/zephyr/single_loader.cI could find no Zephyr API call, noCONFIG_*reference and no devicetree use; its includes are
assert.h,bootutil/*,bootutil_priv.handmcuboot_config/mcuboot_config.h, and the onlynon-bootutil symbols it references are the
BOOT_LOG_*macros, which arealready part of the port configuration contract. The same appears to hold for
the Mynewt version.
Why it matters
boot_go()has two implementations — the multi-slot state machine inboot/bootutil/src/loader.c, and the single-slot path — and the build systemselects between them (
boot/zephyr/CMakeLists.txt, theCONFIG_SINGLE_APPLICATION_SLOTbranch). Because only the multi-slotimplementation lives in the shared library, an out-of-tree port that wants
single-slot support has to write the second one itself, even though it is
almost entirely calls into
bootutil.That also means the two in-tree copies can drift from each other and from
bootutil, and each has to be updated separately when thebootutilinterfacechanges.
Proposal
Move the OS-independent part of the single-slot boot path into
boot/bootutil/src/single_loader.cand have the Zephyr and Mynewt ports use it,leaving anything genuinely port-specific behind. This would be a
behaviour-preserving refactor rather than a feature change, and would give
out-of-tree ports the same choice of
boot_go()implementation that the in-treeports have.
Questions before attempting a PR
bootutila direction you would accept inprinciple, or is the duplication deliberate?
sim/Cargo.tomlhas features foroverwrite-only,swap-move,swap-offsetand so on, but none for single-slot, so as far as I can tell thesingle-slot path currently has no simulator coverage. For a
behaviour-preserving move, would you want simulator coverage for single-slot
added first (or as part of the same PR), or is the absence of coverage
acceptable for a relocation?
version and have Mynewt adopt it, or reduce to the smaller common subset and
let each port keep what only it needs?
Happy to do the work if the direction is welcome; asking first per
docs/contributing.md.