Migrating child/parent to sysbuild - SECURE BOOT

Hello,

I'm migrating my project from using child/parent to sysbuild (simple Hello world code, and using MCUBOOT + NSIB).

The first error i faced when moving to use sysbuild (when adding SB_CONFIG_SECURE_BOOT_APPCORE) was - 

-- Zephyr version: 3.6.99 (~/ncs/v2.7.0/zephyr), build: v3.6.99-ncs2
[198/198] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       34428 B      48640 B     70.78%
             RAM:       23392 B       256 KB      8.92%
        IDT_LIST:          0 GB        32 KB      0.00%
Generating files from ~/tests/my_app/build_1/s1_image/zephyr/zephyr.elf for board: sc220
[1/134] Preparing syscall dependency handling

[5/134] Generating include/generated/version.h
-- Zephyr version: 3.6.99 (~/ncs/v2.7.0/zephyr), build: v3.6.99-ncs2
[127/134] Building C object zephyr/drivers/console/CMakeFiles/drivers__console.dir/uart_console.c.obj
FAILED: zephyr/drivers/console/CMakeFiles/drivers__console.dir/uart_console.c.obj 
ccache ~/ncs/toolchains/e9dba88316/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc -DEXT_API_MAGIC=0x281ee6de,0xb845acea,13314 -DFIRMWARE_INFO_MAGIC=0x281ee6de,0x8fcebb4c,13314 -DKERNEL -DK_HEAP_MEM_POOL_SIZE=0 -DNRF52840_XXAA -DPICOLIBC_DOUBLE_PRINTF_SCANF -DUSE_PARTITION_MANAGER=1 -DVALIDATION_INFO_MAGIC=0x281ee6de,0x86518483,78850 -DVALIDATION_POINTER_MAGIC=0x281ee6de,0x6919b47e,78850 -D__LINUX_ERRNO_EXTENSIONS__ -D__PROGRAM_START -D__ZEPHYR_SUPERVISOR__ -D__ZEPHYR__=1 -I~/ncs/v2.7.0/zephyr/include -I~/tests/my_app/build_1/b0/zephyr/include/generated -I~/ncs/v2.7.0/zephyr/soc/nordic -I~/ncs/v2.7.0/zephyr/soc/nordic/nrf52/. -I~/ncs/v2.7.0/zephyr/soc/nordic/common/. -I~/ncs/v2.7.0/nrf/include -I~/ncs/v2.7.0/nrf/subsys/bootloader/include -I~/ncs/v2.7.0/nrf/tests/include -I~/ncs/v2.7.0/modules/hal/cmsis/CMSIS/Core/Include -I~/ncs/v2.7.0/zephyr/modules/cmsis/. -I~/ncs/v2.7.0/modules/hal/nordic/nrfx -I~/ncs/v2.7.0/modules/hal/nordic/nrfx/drivers/include -I~/ncs/v2.7.0/modules/hal/nordic/nrfx/mdk -I~/ncs/v2.7.0/zephyr/modules/hal_nordic/nrfx/. -I~/ncs/v2.7.0/nrfxlib/crypto/nrf_oberon/include -I~/ncs/v2.7.0/nrfxlib/crypto/nrf_cc310_bl/include -isystem ~/ncs/v2.7.0/zephyr/lib/libc/common/include -isystem ~/ncs/v2.7.0/nrfxlib/crypto/nrf_cc310_platform/include -Wshadow -fno-strict-aliasing -Os -imacros ~/tests/my_app/build_1/b0/zephyr/include/generated/autoconf.h -fno-common -g -gdwarf-4 -fdiagnostics-color=always -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mfp16-format=ieee -mtp=soft --sysroot=~/ncs/toolchains/e9dba88316/opt/zephyr-sdk/arm-zephyr-eabi/arm-zephyr-eabi -imacros ~/ncs/v2.7.0/zephyr/include/zephyr/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wdouble-promotion -Wno-pointer-sign -Wpointer-arith -Wexpansion-to-defined -Wno-unused-but-set-variable -Werror=implicit-int -fno-pic -fno-pie -fno-asynchronous-unwind-tables -ftls-model=local-exec -fno-reorder-functions --param=min-pagesize=0 -fno-defer-pop -fmacro-prefix-map=~/ncs/v2.7.0/nrf/samples/bootloader=CMAKE_SOURCE_DIR -fmacro-prefix-map=~/ncs/v2.7.0/zephyr=ZEPHYR_BASE -fmacro-prefix-map=~/ncs/v2.7.0=WEST_TOPDIR -ffunction-sections -fdata-sections --specs=picolibc.specs -std=c99 -MD -MT zephyr/drivers/console/CMakeFiles/drivers__console.dir/uart_console.c.obj -MF zephyr/drivers/console/CMakeFiles/drivers__console.dir/uart_console.c.obj.d -o zephyr/drivers/console/CMakeFiles/drivers__console.dir/uart_console.c.obj -c ~/ncs/v2.7.0/zephyr/drivers/console/uart_console.c
In file included from ~/ncs/v2.7.0/zephyr/include/zephyr/toolchain/gcc.h:98,
                 from ~/ncs/v2.7.0/zephyr/include/zephyr/toolchain.h:50,
                 from ~/ncs/v2.7.0/zephyr/include/zephyr/kernel_includes.h:23,
                 from ~/ncs/v2.7.0/zephyr/include/zephyr/kernel.h:17,
                 from ~/ncs/v2.7.0/zephyr/drivers/console/uart_console.c:16:
~/ncs/v2.7.0/zephyr/include/zephyr/device.h:91:41: error: '__device_dts_ord_DT_CHOSEN_zephyr_console_ORD' undeclared here (not in a function)
   91 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
      |                                         ^~~~~~~~~
~/ncs/v2.7.0/zephyr/include/zephyr/toolchain/common.h:137:26: note: in definition of macro '_DO_CONCAT'
  137 | #define _DO_CONCAT(x, y) x ## y
      |                          ^
~/ncs/v2.7.0/zephyr/include/zephyr/device.h:91:33: note: in expansion of macro '_CONCAT'
   91 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
      |                                 ^~~~~~~
~/ncs/v2.7.0/zephyr/include/zephyr/device.h:228:37: note: in expansion of macro 'DEVICE_NAME_GET'
  228 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
      |                                     ^~~~~~~~~~~~~~~
~/ncs/v2.7.0/zephyr/include/zephyr/device.h:245:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
  245 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
      |                                  ^~~~~~~~~~~~~~~~~~
~/ncs/v2.7.0/zephyr/drivers/console/uart_console.c:40:9: note: in expansion of macro 'DEVICE_DT_GET'
   40 |         DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
      |         ^~~~~~~~~~~~~
ninja: build stopped: subcommand failed.
[43/54] Generating ../signed_by_mcuboot_and_b0_mcuboot.bin
image.py: sign the payload
[44/54] Generating ../signed_by_mcuboot_and_b0_mcuboot.hex
image.py: sign the payload
[46/54] Generating ../signed_by_mcuboot_and_b0_s1_image.bin
image.py: sign the payload
[47/54] Generating ../signed_by_mcuboot_and_b0_s1_image.hex
image.py: sign the payload
[48/54] Generating ../dfu_mcuboot.zip
FAILED: modules/nrf/b0-prefix/src/b0-stamp/b0-build ~/tests/my_app/build_1/modules/nrf/b0-prefix/src/b0-stamp/b0-build 
cd ~/tests/my_app/build_1/b0 && ~/ncs/toolchains/e9dba88316/usr/local/bin/cmake --build .
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: ~/ncs/toolchains/e9dba88316/usr/local/bin/cmake --build ~/tests/my_app/build_1

I understand that the error occur because it is looking for zephyr,console in the dts (and also inside sysbuild/mcuboot/my_bsp.overlay).
to solve it temporarly i just added inside chosen node (in the dts and in the sysbuild/mcuboot/MY_BSP.overlaly) -

chosen {
		zephyr,console = &uart0;
	};

Please note that in my BSP there is no use for console with uart. uart0 and uart1 are used with external modules and i can't let the console throw data into the uart lines (will it happen if zepyr,console = &uart0 is selected?).
with the child/parent it worked well (without having the zephyr,console in dts) but now it seems to use it..

This is the project folders structure:

.
├── boards
│	└── vendor
│		└── MY_BSP
│			├── board.cmake
│			├── board.yml
│			├── Kconfig
│			├── Kconfig.MY_BSP
│			├── MY_BSP_defconfig
│			├── MY_BSP.dts
│			├── MY_BSP_nrf52840-pinctrl.dtsi
│			└── MY_BSP.yaml
├── CMakeLists.txt
├── prj.conf
├── MY_BSP.overlay
├── src
│   └── main.c
├── sysbuild
│	└── mcuboot
│		├── app.overlay
│		├── boards
│		│   └── MY_BSP.overlay
│		├── mcuboot.conf
│		└── prj.conf
└── sysbuild.conf


To sum up my questions regard moving to use sysbuild:
1. Why do i have to set the property zephyr,chosen with sysbuild where in child/parent i could build without it(exactly same bsp)?
2. Do i use the correct folder structure and relevant files on the sysbuild?

Side question - when i started to use the sysbuild i took the contents of the .conf files to the relevant .conf files in sysbuild but it didnt worked. - why is that?, in order to make it work i had to create many conf files and they required many properties..


on child/parent this was my prj.conf in parent folder:

CONFIG_GPIO=y
CONFIG_SECURE_BOOT=y

# Enable MCUboot
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

# Enable MCUMGR 
CONFIG_MCUMGR=y

# Enable MCUMGR management for both OS and Images
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_GRP_IMG=y

# Configure dependencies for CONFIG_MCUMGR  
CONFIG_NET_BUF=y
CONFIG_ZCBOR=y
CONFIG_CRC=y

# Configure dependencies for CONFIG_MCUMGR_GRP_IMG  
CONFIG_FLASH=y
CONFIG_IMG_MANAGER=y

# Configure dependencies for CONFIG_IMG_MANAGER  
CONFIG_STREAM_FLASH=y
CONFIG_FLASH_MAP=y

CONFIG_MAIN_STACK_SIZE=2048

CONFIG_PRINTK=y
CONFIG_NORDIC_QSPI_NOR=y
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y



CONFIG_SECURE_BOOT=y
CONFIG_SB_SIGNING_KEY_FILE="ustom_priv.pem"
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="custom_priv.pem"
CONFIG_BUILD_S1_VARIANT=y
CONFIG_SB_NUM_VER_COUNTER_SLOTS=120

CONFIG_NORDIC_QSPI_NOR=y
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y


# Configure MCUMGR transport to UART
CONFIG_MCUMGR_TRANSPORT_UART=y

# Configure dependencies for CONFIG_MCUMGR_TRANSPORT_UART 
CONFIG_BASE64=y

and this was the mcuboot.conf in child_image folder:
# Enable logging for MCUboot
CONFIG_LOG=y
CONFIG_MCUBOOT_LOG_LEVEL_INF=y

# Two slots, as we need two for DFU from the app
CONFIG_SINGLE_APPLICATION_SLOT=n

CONFIG_NORDIC_QSPI_NOR=y

# Increase number of sectors
CONFIG_BOOT_MAX_IMG_SECTORS=256

CONFIG_FW_INFO_FIRMWARE_VERSION=1

The content of the sysbuild .conf files:
app folder/prj.conf:

CONFIG_GPIO=y
CONFIG_TFM_PROFILE_TYPE_NOT_SET=y

CONFIG_TFM_LOG_LEVEL_SILENCE=n
CONFIG_TFM_SPM_LOG_LEVEL_DEBUG=y
CONFIG_TFM_EXCEPTION_INFO_DUMP=y

CONFIG_TFM_PARTITION_INITIAL_ATTESTATION=y
CONFIG_TFM_NRF_PROVISIONING=y

CONFIG_PRINTK=y
# # Disable Console output from UART
CONFIG_CONSOLE=n
# # Use RTT as Console outputs
CONFIG_RTT_CONSOLE=y
CONFIG_UART_CONSOLE=n
CONFIG_USE_SEGGER_RTT=y

# Config logger
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n

CONFIG_SECURE_BOOT=y
CONFIG_BUILD_S1_VARIANT=y

CONFIG_NORDIC_QSPI_NOR=y
# need to check which size is good
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096

# Enable mcumgr.
CONFIG_MCUMGR=y
CONFIG_NET_BUF=y
CONFIG_ZCBOR=y
CONFIG_CRC=y
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_STREAM_FLASH=y
CONFIG_IMG_MANAGER=y
CONFIG_BASE64=y

# Some command handlers require a large stack.
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304
CONFIG_MAIN_STACK_SIZE=2048

# Enable MCUboot so the application is built as MCUboot-compatible image
CONFIG_BOOTLOADER_MCUBOOT=y


# Required by the `taskstat` command.
CONFIG_THREAD_MONITOR=y

# Support for taskstat command
CONFIG_MCUMGR_GRP_OS_TASKSTAT=y

# Enable statistics and statistic names.
CONFIG_STATS=y
CONFIG_STATS_NAMES=y

# Enable most core commands.
CONFIG_MCUMGR_GRP_IMG=y
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_GRP_STAT=y

# Enable logging
CONFIG_LOG=y
CONFIG_MCUBOOT_UTIL_LOG_LEVEL_WRN=y

# Enable the serial mcumgr transport.
CONFIG_MCUMGR_TRANSPORT_UART=y

# Ensure clean log output
CONFIG_LOG_MODE_IMMEDIATE=y

# Enable TFM isolation level 2
CONFIG_TFM_ISOLATION_LEVEL=2

sysbuild/mcuboot/prj.conf:

CONFIG_MAIN_STACK_SIZE=10240
CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h"

CONFIG_BOOT_SWAP_SAVE_ENCTLV=n
CONFIG_BOOT_ENCRYPT_IMAGE=n

CONFIG_BOOT_UPGRADE_ONLY=y # changed from default MCUboot
CONFIG_BOOT_BOOTSTRAP=n
CONFIG_MCUBOOT_DOWNGRADE_PREVENTION=y # changed from default MCUBoot

CONFIG_BOOT_MAX_IMG_SECTORS=256
CONFIG_PRINTK=y
CONFIG_UART_CONSOLE=n
CONFIG_RTT_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y

# Config logger
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n
CONFIG_MULTITHREADING=y

CONFIG_FLASH=y
CONFIG_FPROTECT=y

CONFIG_LOG=y
CONFIG_LOG_MODE_MINIMAL=y
### Ensure Zephyr logging changes don't use more resources
CONFIG_LOG_DEFAULT_LEVEL=0
### Use info log level by default
CONFIG_MCUBOOT_LOG_LEVEL_INF=y
### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y
CONFIG_CBPRINTF_NANO=y
CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0
### Enable fault injection hardening
CONFIG_BOOT_FIH_PROFILE_MEDIUM=y
### Enable ECDSA P256 signing/verification
CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
CONFIG_BOOT_SIGNATURE_TYPE_RSA=n
### Use the minimal C library to reduce flash usage
CONFIG_MINIMAL_LIBC=y

CONFIG_PM_PARTITION_SIZE_MCUBOOT=0xbe00

# Disable UART Console and enable the RTT console
CONFIG_CONSOLE=n
CONFIG_SERIAL=n

sysbuid/mcuboot/mcuboot.conf:

# Disable UART Console and enable the RTT console
CONFIG_LOG=y
CONFIG_UART_CONSOLE=n
CONFIG_CONSOLE=n
CONFIG_SERIAL=n
CONFIG_RTT_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y

# Config logger
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n
CONFIG_MULTITHREADING=y

Thanks,
Udi

  • Hi Udi,

    Let me investigate this and follow up with you in a few days.

    Regards,

    Hieu

  • Hi Udi,

    1. Why do i have to set the property zephyr,chosen with sysbuild where in child/parent i could build without it(exactly same bsp)?

    Could you please check if CONFIG_CONSOLE is enabled in any of your images?

    Please note that in my BSP there is no use for console with uart. uart0 and uart1 are used with external modules and i can't let the console throw data into the uart lines (will it happen if zepyr,console = &uart0 is selected?).

    The console is used for a few things. printk() will output to the console unless configured otherwise, for example.

    If you require that nothing is output to the console, then you might want to pay attention to the boot banner.

    But of course, the safest method is to just disable console altogether.

    2. Do i use the correct folder structure and relevant files on the sysbuild?

    I will come back later for this. Unfortunately, I am new to sysbuild myself.

    Regards,

    Hieu

  • Sorry that it took me while to respond.

    Could you please check if CONFIG_CONSOLE is enabled in any of your images?

    Actually there is a weird thing, in my prj.conf it is set to CONFIG_CONSOLE=n but in the .config file (build/b0/zephyr/.config) it is set to CONFIG_CONSOLE=y.

    any idea why?

  • Udi Vahaba said:

    Sorry that it took me while to respond.

    Could you please check if CONFIG_CONSOLE is enabled in any of your images?

    Actually there is a weird thing, in my prj.conf it is set to CONFIG_CONSOLE=n but in the .config file (build/b0/zephyr/.config) it is set to CONFIG_CONSOLE=y.

    any idea why?

    Your prj.conf configures your application. b0 is a different image, so the configuration in prj.conf isn't applied to it. See this documentation page: https://docs.nordicsemi.com/bundle/ncs-2.7.0/page/zephyr/build/sysbuild/index.html.

    2. Do i use the correct folder structure and relevant files on the sysbuild?

    Regarding your folder structure, I don't think sysbuid/mcuboot/mcuboot.conf has any effect. 
    The idea of having it is also rather redundant, as you are reconfiguring the entire project Kconfig file with sysbuild/mcuboot/prj.conf.

    What you want to do is merge your previous child_image/mcuboot.conf content into sysbuid/mcuboot/prj.conf, or do not have the sysbuild/mcuboot directory, and only use sysbuild/mcuboot.conf.

    This is also discussed in the documentation page linked above.

    Other than that, the project structure looks OK.

    As for your configuration file content, unfortunately, I cannot provide any guarantee regarding the config file contents.
    I can see that you have made modifications to MCUboot configuration, and all I can say is that the configurations that are changed are meant to be configurable.
    Whether that achieve what you want or not is, however, entirely up to your own project requirements and verifying them require proper testing.

    The same can be said for <application>/prj.conf. It depends largely on your project requirements and requires testing.
    I have some doubt about whether you need to set CONFIG_BUILD_WITH_TFM on your own when using sysbuild. I have raised this internally and follow-up when I get a reply.
    The MCUmgr configurations for the image management group, which is relevant to DFU, look OK.

    Other than that, no comment about the other changes compared to your pre-sysbuild prj.conf.

Related