Sysbuild: A solution to multi-image build complexity

Sysbuild: A solution to multi-image build complexity

Building embedded applications often means managing multiple firmware images, like bootloaders, application firmware, and secondary core firmware. While a single-image build is relatively straightforward, multi-image builds, where multiple firmware images need to coexist and interact, bring challenges that require a more structured approach.

In this blog post, we'll discuss the motivations behind Sysbuild, why it was introduced, the problems it solved compared to previous solutions, and how developers can use it effectively in their applications.

The challenge with multi-image builds

For embedded devices with multiple cores or those involving separate application and bootloader firmware, several complexities arise:

  1. Partition management: Memory must be carefully partitioned to prevent overlap between images. Each image needs its own independent section of flash and RAM, aligned with its functional requirements.

  2. Dependency management: Images often depend on each other. For example, the bootloader must securely give control to the application image, which requires both to be configured correctly relative to each other.

  3. Build complexity: Building, flashing, and debugging multiple images can be cumbersome without automation. Developers frequently end up juggling different build and configuration setups manually.

  4. Scalability: As projects gain more images or features (e.g., secondary core functionality), manually handling configurations becomes increasingly error-prone.

Previous solution: Parent-child image

Before introducing Sysbuild, the nRF Connect SDK used a parent-child image approach for multi-image builds.

This approach revealed some limitations:

  • Hard dependency: The parent image controlled which images were added, their configuration files, and the packaging of firmware components. This dependency made it less flexible and harder to manage complex multi-image projects, especially as the number of images grew.

  • Configuration complexity: Configuration values (like file suffixes, shields, and snippets) only applied to the main application unless explicitly prefixed, which could lead to confusion and misconfiguration in multi-image builds. Sysbuild applies these globally unless prefixed, making the configuration more predictable and manageable.

  • Lack of namespacing and output management: Output files in the parent-child system were not namespaced, which could cause conflicts and confusion when handling multiple images. Sysbuild introduces namespaced output files, making it easier to identify and manage outputs for each image.

  • Limited extensibility: Scaling for new use cases, such as multicore systems or advanced bootloader requirements, pushed this design to its limits. In some cases, workarounds were implemented that detracted from maintainability.

These issues were part of why the parent-child system remained an nRF Connect SDK-specific method, while upstream Zephyr had no mechanism for handling multi-image builds.

The need for a more general and flexible solution became apparent.

Enter Sysbuild, the high-level build solution

What is it?

Sysbuild, short for system build, is a top-level Zephyr project used to combine multiple other build systems. It supports configuring the build system through centralized Kconfig options and can be extended by modules and user applications. 

First included in nRF Connect SDK v2.7.0 and enabled by default in v2.8.0, Sysbuild was developed by Nordic and contributed upstream to bring multi-image support into Zephyr. Drawing on lessons learned from the earlier parent-child method, Sysbuild was designed to capture the best ideas from that approach while avoiding its limitations. 

Sysbuild configuration rules

Sysbuild can configure the other images in the build system, but the images can not apply configuration to each other or to Sysbuild.

The image depicts the Sysbuild configuration rules:

  1. Sysbuild configuration can add a feature that affects only Sysbuild.

  2. Sysbuild configuration can cause changes in the application configuration.

  3. Sysbuild configuration can cause changes in the extra image configuration.

  4. Sysbuild configuration can spawn new images.

  5. Application configuration cannot affect Sysbuild configuration or Extra image configuration.

Key benefits of Sysbuild

  1. Multi-image extensibility: Developers can easily add multiple images in a hierarchical build structure. Whether it's a bootloader like MCUboot or secondary core images, Sysbuild supports a wide range of use cases.

  2. Flexibility in configuration: Sysbuild uses specific Kconfig options prefixed with SB_ to configure Sysbuild independently of the individual images. It also supports configuring the other images with centralised Kconfig options. 

  3. Clear separation of ownership: The applications deal only with themselves, not other images, and Sysbuild is used to bind the images together centrally.
  4. Supported natively in Zephyr: Unlike previous solutions, Sysbuild is supported natively in Zephyr and with Zephyr tools (e.g., west), which means direct integration with other Zephyr features, such as Hardware Model v2. It also means it is maintained upstream and has community inputs and fixes.

  5. Improved scalability: Whether working with multi-image bootloaders, multicore SoCs, or other complex scenarios, Sysbuild lets you create and manage custom images alongside SDK-provided ones.

The improvement isn't just in tooling, it's a shift in how multi-image builds are conceptualized. Sysbuild provides a hierarchical structure where images can be developed independently yet coexist transparently within a single build system.

Sysbuild images

To include additional images using Sysbuild, enable the corresponding Sysbuild Kconfig option (prefixed with SB_CONFIG) in the central Sysbuild configuration, which is typically done in a sysbuild.conf file in the application.

nRF Connect SDK has pre-made images available, such as the IPC radio firmware and MCUboot, which can easily be pulled into the build by enabling the corresponding Kconfig symbol in the Sysbuild configuration, e.g., SB_CONFIG_NETCORE_IPC_RADIO.

Adding MCUboot using Sysbuild

A common need for multi-image builds is adding a bootloader, such as MCUboot, to your application. Thanks to Sysbuild, pulling in existing nRF Connect SDK images into your build is now very simple.

Create the sysbuild.conf file in your project root and enable the following Kconfig:

SB_CONFIG_BOOTLOADER_MCUBOOT=y

Sysbuild Kconfig symbols differ from application Kconfig options by the SB_ prefix (SB_CONFIG_), and they are set in a file named sysbuild.conf in the application root.

To configure MCUboot, create a folder called sysbuild/ in the project root and add a file named mcuboot.conf.

Then add the Kconfig symbols you want to apply to the MCUboot image. For instance, if we no longer want to get any logs over UART from MCUboot, we can disable CONFIG_SERIAL.

CONFIG_SERIAL=n
Build the application as normal, and look at the following files to verify the configuration:

MCUboot: build/mcuboot/zephyr/.config

Application: build/<application_name>/zephyr/.config

Closing

By introducing Sysbuild, the nRF Connect SDK has transformed multi-image build management from a tangled web of parent-child configuration to a streamlined, hierarchical solution. Developers now benefit from flexibility, scalability, and extensibility, making it easier to tackle complex projects for modern SoCs.

Whether you're enabling a bootloader, developing multicore firmware, or creating custom secondary images, Sysbuild provides the tools you need for efficient development and debugging. As you explore its features, you'll find it a vital component for effortlessly building connected devices.

If you want to learn more about Sysbuild, Lesson 8 - Sysbuild in the nRF Connect SDK Intermediate course on DevAcademy goes into depth on Sysbuild; what it is, how to configure it, and dynamic partitioning using the Partition Manager. It also includes two hands-on exercises that teach you how to configure an extra image in your application and add a custom image.

This blog post merely scratches the surface; we encourage you to dive deeper into the Sysbuild lesson, documentation, and related SDK samples. Happy building!