Skip to main content

SWUpdate Customization

Introduction

This guide demonstrates how to customize SWUpdate configuration and behavior within a Yocto-based Linux system. You'll learn how to modify update content, adjust features, configure hardware compatibility, and fine-tune hawkBit server integration to meet your specific deployment requirements.

Prerequisites

  • Yocto Version: Yocto 5.2 (Walnascar) or later
  • Yocto Build Environment: Ensure your development system is configured to build Yocto projects. Refer to:
  • Hardware: Target board with sufficient storage (eMMC or SD card)
  • Network: Ethernet or WiFi connectivity for OTA updates
  • Base SWUpdate Setup: Complete the basic setup before customization

Set Up Environment

Before customizing SWUpdate, complete Steps 1-3 from Building SWUpdate Inside RootFS From Yocto:

  1. Clone Yocto source code
  2. Set up the build environment
  3. Configure SWUpdate and Suricatta Settings

This ensures you have a working base configuration before making customizations.

Generate SWUpdate Encryption Keys

SWUpdate uses cryptographic signatures to verify update images. Generate RSA key pairs for signing:

# Create a passphrase file (keep this secure!)
echo 123456 > passphrase

# Generate private key (AES-256 encrypted)
openssl genrsa -aes256 -passout file:passphrase -out swu_priv.pem

# Extract public key
openssl rsa -in swu_priv.pem -passin file:passphrase -out swu_public.pem -outform PEM -pubout

Key File Placement

Place the generated keys in the following locations within your Yocto source tree:

Private key and passphrase (used during build):

source/meta-tn-imx-bsp/dynamic-layers/swupdate/recipes-extended/images/update-image/
├── swu_priv.pem
└── passphrase

Public key (embedded in rootfs for verification):

source/meta-tn-imx-bsp/dynamic-layers/swupdate/recipes-support/swupdate/swupdate/swu_public.pem

The public key will be installed to /etc/swu_public.pem on the target board.

Security Notice

The passphrase and swu_priv.pem files contain sensitive cryptographic material. Store them securely and never commit them to version control. Consider using a hardware security module (HSM) for production environments.

Alternative Methods

For other key generation methods and signature algorithms, see the SWUpdate documentation on signed images.

Customization Overview

SWUpdate customization typically involves modifying these key components:

ComponentFile LocationPurpose
Update Contentsw-descriptionDefine what gets updated and how
Feature ConfigurationdefconfigEnable/disable SWUpdate features
Hardware Compatibilityswupdate_%.bbappendSet hardware version matching
Server Settingsswupdate.cfgConfigure hawkBit/Suricatta parameters

1. Customizing Update Content

The sw-description file defines what components are included in your update package and how they should be installed.

File Location

source/meta-tn-imx-bsp/dynamic-layers/swupdate/recipes-extended/images/update-image/sw-description

What Can Be Updated

SWUpdate supports updating various system components:

  • Bootloader (U-Boot, SPL)
  • Kernel (Linux kernel image)
  • Device Tree (DTB files)
  • Root Filesystem (Complete or partial)
  • Applications (User-space programs)
  • Firmware (Device firmware blobs)
  • U-Boot Environment (Boot configuration variables)

Basic sw-description Structure

software =
{
version = "1.0.0";

hardware-compatibility: [ "1.0", "1.2", "1.3" ];

images: (
{
filename = "rootfs.ext4.gz";
device = "/dev/mmcblk1p2";
type = "raw";
compressed = "zlib";
installed-directly = true;
}
);

scripts: (
{
filename = "post-install.sh";
type = "shellscript";
}
);

bootenv: (
{
name = "bootcount";
value = "0";
}
);
}

Common Configuration Options

OptionDescriptionExample Values
filenameName of file in .swu package"rootfs.ext4.gz"
deviceTarget device/partition"/dev/mmcblk1p2"
typeHandler type"raw", "ubifs", "flash"
compressedCompression algorithm"zlib", "gzip", "none"
installed-directlySkip temp extractiontrue, false
sha256Checksum for verificationHash string

Example: Updating Multiple Components

software =
{
version = "2.5.0";

hardware-compatibility: [ "1.0" ];

images: (
{
filename = "imx-boot";
device = "/dev/mmcblk1boot0";
type = "raw";
},
{
filename = "Image";
device = "/dev/mmcblk1p1";
type = "raw";
},
{
filename = "imx8mp-edm-g-wb.dtb";
device = "/dev/mmcblk1p1";
offset = "0x100000";
type = "raw";
},
{
filename = "rootfs.ext4.gz";
device = "/dev/mmcblk1p2";
type = "raw";
compressed = "zlib";
installed-directly = true;
}
);

scripts: (
{
filename = "pre-install.sh";
type = "shellscript";
},
{
filename = "post-install.sh";
type = "shellscript";
}
);
}

Advanced: Conditional Updates

You can use Lua scripting for conditional logic:

function check_version()
local current_version = get_bootenv("version")
if current_version == "1.0.0" then
return true, "Update allowed"
else
return false, "Version mismatch"
end
end
Documentation

For complete syntax reference and advanced features, see SWUpdate: sw-description syntax and tags

2. Adjusting SWUpdate Features

The defconfig file controls which SWUpdate features are compiled into the binary.

File Location

source/meta-tn-imx-bsp/dynamic-layers/swupdate/recipes-support/swupdate/swupdate/defconfig

Common Feature Options

# Web server interface
CONFIG_MONGOOSE=y
CONFIG_MONGOOSEIPV6=y
CONFIG_MONGOOSESSL=n

# Remote update support
CONFIG_SURICATTA=y
CONFIG_SURICATTA_HAWKBIT=y
CONFIG_SURICATTA_SSL=y

# Signature verification
CONFIG_SIGNED_IMAGES=y
CONFIG_SIGALG_RSA=y
CONFIG_SSL_IMPL_OPENSSL=y

# Download support
CONFIG_DOWNLOAD=y
CONFIG_DOWNLOAD_SSL=y
CONFIG_CHANNEL_CURL=y

# Handler support
CONFIG_HANDLER_SCRIPT=y
CONFIG_HANDLER_RAW=y
CONFIG_HANDLER_UBOOT=y

# Compression support
CONFIG_GUNZIP=y
CONFIG_ZLIB=y
CONFIG_ZSTD=y

# Logging
CONFIG_BOOTLOADER_EBG=y
CONFIG_SYSTEMD=y

Feature Categories

CategoryOptionsPurpose
Web InterfaceCONFIG_MONGOOSEEnable built-in web server
Remote UpdatesCONFIG_SURICATTA_*hawkBit integration
SecurityCONFIG_SIGNED_IMAGESImage verification
HandlersCONFIG_HANDLER_*Update type support
CompressionCONFIG_GUNZIP, CONFIG_ZSTDDecompression algorithms

Enabling/Disabling Features

To enable a feature:

CONFIG_FEATURE_NAME=y

To disable a feature:

CONFIG_FEATURE_NAME=n
# or comment it out:
# CONFIG_FEATURE_NAME=y
Important

After modifying defconfig, you must rebuild SWUpdate:

bitbake swupdate-image -c cleansstate
bitbake swupdate-image

3. Configuring Hardware Compatibility

Hardware compatibility prevents installing updates on incompatible devices, protecting against bricking devices with wrong firmware.

File Location

source/meta-tn-imx-bsp/dynamic-layers/swupdate/recipes-support/swupdate/swupdate_%.bbappend

Default Configuration

SWU_HW_REV ?= "1.0"

Setting Hardware Version

Method 1: Modify bbappend file directly

Edit swupdate_%.bbappend:

SWU_HW_REV ?= "2.0"

Method 2: Override in local.conf

Add to conf/local.conf:

SWU_HW_REV = "2.0"

Multiple Hardware Revisions

In your sw-description, specify all compatible hardware versions:

hardware-compatibility: [ "1.0", "1.2", "1.3", "2.0" ];

This allows the same update package to work on multiple hardware revisions.

Hardware Version Checking

SWUpdate reads the hardware version from:

/etc/hwrevision

This file is automatically generated during build using the SWU_HW_REV variable.

Custom Hardware Detection

For complex hardware detection, you can use a script:

Create custom hwrevision script:

#!/bin/sh
# Read hardware revision from EEPROM or other source
hw_rev=$(i2cget -y 0 0x50 0x10)
echo "$hw_rev" > /etc/hwrevision
Production Use

Use meaningful version strings that reflect actual hardware changes:

  • "imx8mp-rev-a", "imx8mp-rev-b" for board revisions
  • "edm-g-imx8mp-v1.0" for complete identifiers
  • "prototype", "production" for development stages

4. Configuring Suricatta for hawkBit Server

Suricatta is SWUpdate's daemon that communicates with OTA servers like hawkBit.

File Location

source/meta-tn-imx-bsp/dynamic-layers/swupdate/recipes-support/swupdate/swupdate/swupdate.cfg

Default Configuration

suricatta :
{
enable = true;
tenant = "default";
id = "@TARGETID@";
url = "@SERVERURL@";
polldelay = 60;
nocheckcert = true;
retry = 4;
retrywait = 200;
loglevel = 10;
userid = 0;
groupid = 0;
targettoken = "@TARGETTOKEN@";
};

Configuration Parameters

ParameterTypeDescriptionDefaultRecommended
enablebooleanEnable Suricatta daemontruetrue
tenantstringhawkBit tenant name"default"Organization name
idstringTarget device ID (controllerId)@TARGETID@Unique per device
urlstringhawkBit server URL@SERVERURL@Your server address
polldelayintegerPolling interval (seconds)60300-600 for production
nocheckcertbooleanSkip SSL certificate verificationtruefalse for production
retryintegerNumber of retry attempts43-5
retrywaitintegerWait between retries (seconds)200300-600
loglevelintegerLogging verbosity (0-10)105 for production
useridintegerUser ID for process0 (root)Non-zero for security
groupidintegerGroup ID for process0 (root)Non-zero for security
targettokenstringSecurity token@TARGETTOKEN@Unique secure token

Variable Substitution

The @VARIABLE@ placeholders are replaced during build:

  • @TARGETID@SWU_TARGETID from local.conf
  • @SERVERURL@SWU_SERVER from local.conf
  • @TARGETTOKEN@SWU_TARGETTOKEN from local.conf

Production Configuration Example

suricatta :
{
enable = true;
tenant = "production";
id = "@TARGETID@";
url = "@SERVERURL@";
polldelay = 300; // Poll every 5 minutes
nocheckcert = false; // Verify SSL certificates
retry = 5;
retrywait = 300;
loglevel = 5; // Moderate logging
userid = 1000; // Non-root user
groupid = 1000; // Non-root group
targettoken = "@TARGETTOKEN@";

// Gateway configuration (if using proxy)
gatewaytimeout = 60;
};

SSL/TLS Configuration

For production with SSL certificate verification:

suricatta :
{
nocheckcert = false;
cafile = "/etc/ssl/certs/ca-bundle.crt";
sslkey = "/etc/swupdate/client-key.pem";
sslcert = "/etc/swupdate/client-cert.pem";
};

Advanced: Custom Retry Logic

suricatta :
{
retry = 10;
retrywait = 60;
exponential_backoff = true; // If supported
max_retrywait = 3600; // Maximum 1 hour wait
};

Logging Levels

LevelDescriptionUse Case
0No loggingNever recommended
1-2Critical errors onlyProduction (minimal)
3-5Errors and warningsProduction (normal)
6-8Info messagesDevelopment
9-10Debug messagesTroubleshooting
Security Consideration

Setting nocheckcert = true disables SSL certificate verification, making the connection vulnerable to man-in-the-middle attacks. Only use this for testing on trusted networks.

5. Build and Deploy Custom Configuration

After making customizations, rebuild the images:

# Clean previous builds
bitbake swupdate-image -c cleansstate
bitbake update-image -c cleansstate

# Rebuild with new configuration
bitbake swupdate-image
bitbake imx-image-full
bitbake update-image

Verify Customizations

After flashing to the device, verify your customizations:

Check hardware version:

cat /etc/hwrevision

Check SWUpdate configuration:

cat /etc/swupdate.cfg

Check public key:

cat /etc/swu_public.pem

Test update with verbose logging:

swupdate -v -i /path/to/update.swu

Best Practices

Configuration Management

  1. Version Control: Track all customization files in git
  2. Documentation: Document why each customization was made
  3. Testing: Test customizations on development boards first
  4. Backup: Keep backup copies of working configurations

Security Considerations

  1. Key Management: Never commit private keys to version control
  2. Certificate Validation: Enable SSL certificate verification in production
  3. User Privileges: Run Suricatta as non-root user when possible
  4. Token Rotation: Regularly rotate security tokens

Performance Optimization

  1. Poll Delay: Increase polldelay for battery-powered devices
  2. Compression: Choose compression algorithm based on file size and CPU capability
  3. Direct Installation: Use installed-directly = true for large images
  4. Retry Strategy: Balance between persistence and network load

Maintenance

  1. Regular Updates: Keep SWUpdate version updated
  2. Log Monitoring: Regularly review logs for issues
  3. Testing: Test updates on staging environment first
  4. Rollback Plan: Always have a rollback strategy

Troubleshooting

Configuration Not Applied

Problem: Changes to configuration files don't take effect

Solution:

# Clean and rebuild
bitbake swupdate-image -c cleansstate
bitbake swupdate-image

Hardware Mismatch Error

Problem: Update fails with hardware compatibility error

Solution:

  1. Check device hardware version: cat /etc/hwrevision
  2. Verify sw-description includes this version in hardware-compatibility
  3. Update SWU_HW_REV if needed

Suricatta Connection Failures

Problem: Device cannot connect to hawkBit server

Solution:

  1. Verify network connectivity: ping <server-ip>
  2. Check URL and port in /etc/swupdate.cfg
  3. Review logs: journalctl -u swupdate -n 100
  4. Verify firewall rules allow connection

Custom Handler Not Working

Problem: Custom handler not executed during update

Solution:

  1. Verify handler is enabled in defconfig
  2. Check handler registration in code
  3. Test handler independently
  4. Review SWUpdate logs for handler errors

Additional Resources

Next Steps

After customizing SWUpdate:

  1. Test all customizations thoroughly on development hardware
  2. Document your configuration choices for team reference
  3. Set up automated testing for update procedures
  4. Plan for configuration management across device fleet
  5. Implement monitoring and alerting for update operations