Migration from NCS v2.1.3 to v2.6.0 with prebuilt B0 binaries

Hello,

We are in the process of migrating from NCS v2.1.3 to NCS v2.6.0.

Since we have many devices fielded already, one of our requirements is to continue using pre-built hex files for NSIB/B0 and mcuboot.
As such, we also have a separate pre-built hex file to provision our public key hashes to the OTP region.

Our pre-built hex files predate the following features of the NSIB introduced in v2.2.0:

  • PRoT lifecycle state
  • Implementation ID

The addition of this new data to the OTP region would not be a problem in itself, but it seems to have also brought a breaking change to the build process.

  • In NCS v2.6.0, provision.hex is always generated and appended to merged.hex even when using CONFIG_B0_BUILD_STRATEGY_USE_HEX_FILE=y.
    • I do not know if this behavior is true for v2.2.0 - v2.5.0; we will not be doing any migrations to those versions.
  • In NCS v2.1.3, provision.hex is not appended to merged.hex when using CONFIG_B0_BUILD_STRATEGY_USE_HEX_FILE=y.

We want to generate one set of binaries without provision.hex, and one set with provision.hex (for the manufacturing process).

When trying to create the latter set, mergehex fails with the following error message:


mergehex -m /path/to/prebuilt/provision.hex build/zephyr/merged.hex -o merged-with-provision.hex
Parsing input files.
Merging file "provision.hex" into output.
Merging file "merged.hex" into output.
Overlapping segments detected at address 16744752.ERROR: The hex files cannot be merged since there are conflicts.
ninja: build stopped: subcommand failed.


It is not possible to use the generated provision.hex even with the same public keys because the offset of data in provision.hex now accounts for PRoT lifecycle state and Implementation ID. Our old, pre-built bootloaders will not have knowledge of this layout change for the bl_storage library.

For now as a workaround I will be stripping the generated provision.hex as a post-build step, but this is very tedious to maintain; what if build output paths/filenames change in the future?

My questions boil down to:

  • Is there a white paper or migration guide detailing how applications with B0 built from NCS <=v2.1.x should proceed? I was surprised to find no migration guide for NCS v2.2.0...
  • Is there a Kconfig option to control this behavior -- that is, to prevent generating & merging provision.hex? I cannot find one documented.

Thank you in advance for your guidance!

Parents
  • Hi,

    We do not have a solution for this at the moment. However, perhaps you can do something like this:

    1. Get the merged output file that contain everything which you find here: <build folder>/zephyr/merged.hex.
    2. Take the immutable bootloader from the old build (which you find under <build folder>/b0/zephyr/zephyr.hex

    Then do like this:

    python <NCS folder>/zephyr/scripts/build/mergehex.py -o merged_with_old_b0.hex --overlap=replace <path to new merged.hex file> <path to old b0 zephyr.hex file>

    If you do this separately/in some custom build script you can replace the bootloader(s) wihtout needing updates in the build system. Of course building bootloader(s) you don't use and supsequently overwriting them in the merged .hex file is not very elegant, but it should function as a workaround.

Reply
  • Hi,

    We do not have a solution for this at the moment. However, perhaps you can do something like this:

    1. Get the merged output file that contain everything which you find here: <build folder>/zephyr/merged.hex.
    2. Take the immutable bootloader from the old build (which you find under <build folder>/b0/zephyr/zephyr.hex

    Then do like this:

    python <NCS folder>/zephyr/scripts/build/mergehex.py -o merged_with_old_b0.hex --overlap=replace <path to new merged.hex file> <path to old b0 zephyr.hex file>

    If you do this separately/in some custom build script you can replace the bootloader(s) wihtout needing updates in the build system. Of course building bootloader(s) you don't use and supsequently overwriting them in the merged .hex file is not very elegant, but it should function as a workaround.

Children
  • Hi Einar,

    Thank you for the suggested workaround

    I managed to implement it in CMake so that it will be automatic and replace the default merged.hex. Thought I would share it here for future readers.

    list(APPEND TO_MERGE
        # Pre-built B0 bootloader
        ${CONFIG_B0_HEX_FILE}
        # Mcuboot built from source, signed for B0
        # You can also use CONFIG_MCUBOOT_HEX_FILE if using a pre-built mcuboot.
        ${CMAKE_BINARY_DIR}/zephyr/signed_by_b0_s0_image.hex
        # TFM+Application built from source, signed for mcuboot
        ${CMAKE_BINARY_DIR}/zephyr/app_signed.hex
    )
    
    set(MERGED_HEX ${CMAKE_BINARY_DIR}/zephyr/merged.hex)
    set(MERGED_FIXED_HEX ${CMAKE_BINARY_DIR}/zephyr/merged-fixed.hex)
    
    # Manually merge the components of the final binary, excluding provision.hex
    add_custom_command(
        OUTPUT ${MERGED_FIXED_HEX}
        DEPENDS ${TO_MERGE}
        COMMAND
            ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py
            -o ${MERGED_FIXED_HEX}
            --overlap=replace
            ${TO_MERGE}
        )
    add_custom_target(merged_fixed_hex
        ALL
        COMMENT "Creating patched merged.hex"
        DEPENDS ${TO_MERGE}
        )
    
    # Unconditionally copy our merged binary over the default merged.hex
    # so we can use west flash as normal.
    # The DEPENDS clause ensures it always runs after the
    # hex files of interest are generated.
    add_custom_target(patch_merged_hex
        ALL
        COMMENT "Replacing NCS merged.hex with ours"
        COMMAND
            ${CMAKE_COMMAND} -E copy ${MERGED_FIXED_HEX} ${MERGED_HEX}
        DEPENDS ${MERGED_HEX} ${MERGED_FIXED_HEX}
        )

    If like us your B0 binary is from NCS <=v2.1.3, then you cannot use the generated provision.hex in NCS v2.2.0+; however, if you disable the generation of provision.hex, then MCUBoot source builds will not be signed for B0. You can also use a prebuilt MCUBoot hex file to avoid that problem, but this demonstrates how you would merge with an update image for MCUBoot in S0/S1.

    For our application we generate one binary with provision.hex, and one without. For the binary with provision.hex, I have the pre-generated provision.hex that paired with the B0 binary for NCS v2.1.3. We simply add that file to the list of hex files to merge.

Related