nRF53 Custom b0n Build

I am trying to compile a custom bootloader for nRF5340 net core (b0n) that is part of a multi-image build.

I have created two separate applications, one based on b0n (nrf/samples/nrf5340/netboot) and one based on nrf/samples/bluetooth/peripheral_lbs. These both build without issue when used as single image applications and I can debug them (using hello_world on the app core) and they appear to work.

I have tried adding the b0n as a child image of the application by adding the following code to CMakeLists.txt

if (CONFIG_SECURE_BOOT)
  add_child_image(
    NAME b0n
    SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../boot_stage1
  )
endif()

If I then build the net app, the application builds, but b0n is neither built nor linked.

I have tried adding CONFIG_SECURE_BOOT=y to the prj.conf file. If I have the above CMakeLists.txt change, I get the following compilation error:

=== child image b0n -  begin ===
loading initial cache file C:/Users/anton/src/bootloader-test/netapp/build/b0n/child_image_preload.cmake
CMake Error: The source "C:/Users/anton/src/bootloader-test/boot_stage1/CMakeLists.txt" does not match the source "C:/Users/anton/ncs/v1.9.1/nrf/samples/nrf5340/netboot/CMakeLists.txt" used to generate cache.  Re-run cmake with a different source directory.
CMake Error at C:\Users\anton\ncs\v1.9.1\nrf\cmake\multi_image.cmake:409 (message):
  CMake generation for b0n failed, aborting.  Command: 1
Call Stack (most recent call first):
  C:\Users\anton\ncs\v1.9.1\nrf\cmake\multi_image.cmake:150 (add_child_image_from_source)
  c:\Users\anton\src\bootloader-test\netapp\build\CMakeLists.txt:21 (add_child_image)
This confuses me in the following ways
  • I don't know why the netboot sample should be used to generate the cache.
  • The CMakeLists.txt are identical in both the sample and in my local build.
  • I don't know why they need to match anyway.

What is going wrong here?

p.s. Most of the documnetation about multi-image bootloader builds suggest using CONFIG_B0_BUILD_STRATEGY_FROM_SOURCE=y. There doesn't appear to be an equivalent CONFIG_B0N_BUILD_STRATEGY_FROM_SOURCE.

Parents Reply Children
  • The CMakeLists.txt that I am referring to is the root level CMakeLists.txt for the application on the net core (based on nrf/samples/bluetooth/peripheral_lbs on the net core).

    I think you are mistaken: b0 is the app core bootloader, b0n is the net core bootloader (https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/samples/nrf5340/netboot/README.html). Also, as I have said, I can compile and run b0n on the net core without issue. Also, b0n isn't used alongside the bootloader, it is a bootloader. Did you mean it is often run alongside mcuboot as a set of first and second stage bootloaders?

    Edited: I attempted to build the b0n/app using app core but that failed as it was unable to find "pm_config.h" ... but I don't think that is the correct path to follow anyway.

  • Hi

    I explain a bunch of context. However, it might not be super-relevant for you until the red text further down.

    I agree with you here, I were unspecific in my previous answer.
    b0n is the bootloader for the network core.
    For the application core, you can use b0 and/or MCUBoot as a bootloader.

    For a typical example for use of b0n, with context:
    Our Machine Learning sample has configurations for bootloader support on the nRF5340.
    In this sample, MCUBoot is running on the Application Core, while b0n is running at the Network Core.
    To update the firmware, the nRF5340 has to enter Serial Recovery mode or using the Simple Management Protocol over Bluetooth.
    This will use the mcumgr tool to upload an image to the application core, which is then swapped to the network core using Peripheral CPU DFU (PCD).
    When you now reboot, b0n will boot into the new image.

    So when i sat "alongside", I really mean that it is generally not the only bootloader running on the nRF5340.

    I should point out that use of the b0n is a bit weird in the sense of multi-images.
    Normally, you can use overlays in your project to change the configurations of your child images.
    Or you could add a custom child image to your project, to avoid making changes to the nRF Connect SDK directly.
    When using the nRF5340, the code running on the network core will be built as a child image of the application.
    For example, if CONFIG_BT=y when you build for your nrf5340dk_nrf5340, the child image hci_rpmsg is added to your project.

    However, if you want to use the b0n, it is added as a child image of the child image running on the network core. (for example a child_image of hci_rpmsg).
    There is one  way to add a configuration overlay to a "recursive" child image, by nesting their names in CMake variables for child image configurations:

    west build -b nrf5340dk_nrf5340_cpuapp -- -Dhci_rpmsg_b0n_CONFIG_DEBUG=y

    So I think your approach is the best way to add a custom b0n: By first making an custom application for the network core. Then you can add this as a child image when you later make firmware for the network core.
    To try to answer your question:

    If I then build the net app, the application builds, but b0n is neither built nor linked.

    I have not been able to find where in the nRF Connect SDK this is set,
    but I am able to build with a custom b0n if I build hello_world for nrf52840dk_nrf52840_cpuapp with the following configurations:

    CONFIG_BT=y
    CONFIG_SECURE_BOOT=y
    CONFIG_BOOTLOADER_MCUBOOT=y
    

    (Hello World since it is a minimal sample)

    I will continue looking into child images next week, to try to find more for you. If you are able to figure out something in the meantime, let me know.

    Regards,
    Sigurd Hellesvik

  • I assume when you say that you are building a custom b0n for the cpuapp you mean that you are building a custom b0 for the cpuapp.

    So, I can get it to build the b0n image now. I just had to remove the "if (CONFIG_SECURE_BOOT)" and set that config to "n" in the prj.conf for the net application. It then tells me that it cannot add the child image unless "CONFIG_PARTITION_MANAGER_ENABLED" is set to "y". Fine. I do that. Then I get a build error where it cannot find "pm_config.h".

    Now I have chased that down to the following link: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html

    Now that link says that:

    So for some reason the partition manager script must not be running and must not be generating the "pm_config.h" header, or it is not in the correct include path. How do I rectify that?

  • I have tracked it down to the file "partition_manager.cmake", which should make the "pm_config.h" file. This section of code is where it exits before actually creating the header file.

    # This file is executed once per domain.
    #
    # It will be executed if one of the following criteria is true for the
    # current image:
    # - It's a child image, and is the dynamic partition in the domain
    # - It's the root image, and a static configuration has been provided
    # - It's the root image, and PM_IMAGES is populated.
    # - It's the root image, and other domains exist.
    # - A subsys has defined a partition and CONFIG_PM_SINGLE_IMAGE is set.
    # Otherwise, return here
    if (NOT (
      (IMAGE_NAME AND is_dynamic_partition_in_domain) OR
      (NOT IMAGE_NAME AND static_configuration) OR
      (NOT IMAGE_NAME AND PM_IMAGES) OR
      (NOT IMAGE_NAME AND PM_DOMAINS) OR
      (PM_SUBSYS_PREPROCESSED AND CONFIG_PM_SINGLE_IMAGE)
      ))
      return()
    endif()
     
    None of the above are true and so it doesn't create the header file. By adding CMake messages, I can see that:
    • For b0n the IMAGE_NAME is set to b0n and the other parameters are empty. I assume this means that b0n shouldn't build the pm_config.h (which is what I would expect.
    • None of the other parameters are set for the application, which seems wrong.
    • This seems like PM_IMAGES or PM_DOMAINS should not be blank ...

    What should these parameters be? Where should they be set?

  • Hi Anton

    Since b0n and b0 is easily mixed, I will from now on refer to them as follows:

    Network core bootloader: b0n

    Application core nRF Secure Immutable Bootloader: NSIB

    AntonD said:
    I assume when you say that you are building a custom b0n for the cpuapp you mean that you are building a custom b0 for the cpuapp.

    Your assumption is wrong. I am talking about custom b0n.

    AntonD said:
    So for some reason the partition manager script must not be running and must not be generating the "pm_config.h" header, or it is not in the correct include path. How do I rectify that?

    I think that the reason it does not work for you is that the "application design"  we intent to be used for child images is different from the one you use.

    I suggest that you take a step back and look at the overall design.
    Am you making two different projects: One for the APP core and one for the NET core?

    Or are you making one project for the whole nRF5340, like this?

    The second solution is the one I described in my previous post, and the one recommended for nRF5340.

    Regards,
    Sigurd Hellesvik

Related