Skip to content

Yocto integration

The meta-otapulse Yocto layer packages the OTA agent (soc-ota-agent), its configuration template (otapulse.conf), and a systemd service unit into your image. This guide assumes you already have a working Yocto build environment and walks through everything from cloning the layer to confirming the agent is running on-device.

Prerequisites

Yocto release support

ReleaseCompatible
Kirkstone (4.0 LTS)Yes
Langdale (4.1)Yes
Mickledore (4.2)Yes
Nanbield (4.3)Yes
Scarthgap (5.0 LTS)Yes
Earlier releasesNot tested

Compatibility is declared in the layer’s LAYERSERIES_COMPAT_meta-soc-monitoring variable in conf/layer.conf.

Build host

Ubuntu 22.04 or later is recommended. Install the standard Yocto build host packages before continuing. Allow at least 50 GB of free disk space for a fresh build; a warm sstate-cache cuts subsequent builds to 10–20 minutes.

Systemd is required. The layer registers soc-ota-agent.service and depends on systemd as the init manager. If your distro config does not already set INIT_MANAGER = "systemd", add it to local.conf (see below).

Verified hardware

The layer has been tested against BeaglePlay, Raspberry Pi 4 (64-bit), NXP iMX8MM/iMX8MP, and Rockchip RK3588. It is platform-agnostic and will work on any machine your BSP layer supports.

Add the layer

  1. Clone the repository

    From the directory that contains poky/ and meta-openembedded/:

    Terminal window
    git clone https://github.com/intronix/socMonitoring.git

    The Yocto layer lives at ota-pulse/meta-otapulse/ inside the cloned repository.

  2. Add the layer to bblayers.conf

    Edit conf/bblayers.conf in your build directory. Append meta-otapulse and meta-oe (required by the layer):

    BBLAYERS ?= " \
    /path/to/poky/meta \
    /path/to/poky/meta-poky \
    /path/to/poky/meta-yocto-bsp \
    /path/to/meta-openembedded/meta-oe \
    /path/to/ota-pulse/meta-otapulse \
    "

    Replace /path/to/ with the absolute path on your build host. You can also use bitbake-layers add-layer to append the path:

    Terminal window
    bitbake-layers add-layer /path/to/ota-pulse/meta-otapulse

Configure local.conf

Add the following to conf/local.conf in your build directory. Only OTA_SERVER_URL is strictly required for a first build; the signing variables are optional until you enable signature verification.

# --- Required ---
# Install the OTA agent and signing-keys into the image
IMAGE_INSTALL:append = " soc-ota-agent signing-keys"
# Systemd is required by the layer
DISTRO_FEATURES:append = " systemd usrmerge"
INIT_MANAGER = "systemd"
# OTA-Pulse server URL — the agent posts here during updates
OTA_SERVER_URL = "https://your-server.example.com"
# --- Optional: signature verification ---
# Set to "1" to enable artifact signature verification on-device
SOC_OTA_SIGNATURE_VERIFICATION = "0"
# Path where signing-keys recipe installs public keys
SOC_OTA_SIGNING_KEYS_DIR = "/etc/soc-monitoring/signing-keys"
# Space-separated list of public key filenames (relative to the active/ subdirectory)
SOC_OTA_VERIFY_KEY_FILES = "production-rsa-public.pem production-ecdsa-public.pem"

The soc-ota-agent recipe reads OTA_SERVER_URL at build time and writes it into /etc/otapulse/otapulse.conf on the image. The configuration template also sets RootfsPartA and RootfsPartB to /dev/disk/by-partlabel/rootfs_a and rootfs_b respectively, which matches the A/B layout produced by the layer’s WIC kickstart file (see the next section).

Image features and A/B partition layout

The layer ships a WIC kickstart file (wic/soc-monitoring.wks) that defines the A/B partition layout the OTA agent expects:

PartitionLabelSizePurpose
/bootboot100 MBFAT32, kernel + DTB
/rootfs-a1 GBPrimary root filesystem
(unmounted)rootfs-b1 GBInactive slot for OTA writes
/datadata500 MBPersistent data across updates

To use this layout, set the WIC file in local.conf:

WKS_FILE = "soc-monitoring.wks"
IMAGE_FSTYPES = "wic wic.gz wic.bmap ext4"

The reference image recipe (soc-monitoring-image.bb) already sets WKS_FILE ?= "soc-monitoring.wks", so if you build soc-monitoring-image you get this layout automatically. If you are extending a different image recipe, set it explicitly.

Embedding signing keys

To bake your public keys into the image for signature verification, copy them into the recipe’s files directory and set the recipe variables:

Terminal window
# Copy your exported public keys into the layer
cp ~/Downloads/production-rsa-public.pem \
meta-otapulse/recipes-core/signing-keys/files/
cp ~/Downloads/production-ecdsa-public.pem \
meta-otapulse/recipes-core/signing-keys/files/

Then in local.conf:

SOC_OTA_SIGNATURE_VERIFICATION = "1"
SOC_OTA_VERIFY_KEY_FILES = "production-rsa-public.pem production-ecdsa-public.pem"

The signing-keys recipe installs both files under /etc/soc-monitoring/signing-keys/active/ with read-only permissions (0444). The agent reads this directory when ArtifactVerifyKeys is set in its configuration.

You can generate key pairs from the OTA-Pulse console under Settings → Signing Keys (RSA-4096 and ECDSA-P384 are both supported). Save the private key securely — it is shown only once.

First build and verification

Terminal window
source poky/oe-init-build-env build
bitbake soc-monitoring-image

Or, if you are extending your own image recipe:

Terminal window
bitbake <your-image-recipe>

The built WIC image lands in tmp/deploy/images/<MACHINE>/. Flash it to your device:

Terminal window
sudo dd if=tmp/deploy/images/<MACHINE>/soc-monitoring-image-<MACHINE>.wic \
of=/dev/sdX bs=4M status=progress
sync

After boot, verify the agent started successfully:

Terminal window
ssh root@<device-ip>
systemctl status soc-ota-agent
journalctl -u soc-ota-agent --since "1 minute ago"

Within about 30 seconds of the agent starting, the device should appear with an online status badge in the OTA-Pulse console.

Once the device is registered, follow Register your first device for the console-side setup — generating an API key and verifying telemetry is flowing.

Common errors

ERROR: Layer 'meta-soc-monitoring' depends on layer 'meta-oe'

meta-oe is missing from bblayers.conf. Add it:

BBLAYERS += "/path/to/meta-openembedded/meta-oe"

ERROR: Nothing PROVIDES 'soc-ota-agent'

The layer path in bblayers.conf is wrong or the layer was never added. Verify with bitbake-layers show-layersmeta-soc-monitoring must appear in the output (this is the internal Bitbake collection name for the meta-otapulse layer). If it does not, re-run:

Terminal window
bitbake-layers add-layer /path/to/ota-pulse/meta-otapulse

ERROR: LIC_FILES_CHKSUM for soc-ota-agent_1.0.0.bb does not match

A local edit changed the Apache-2.0 license file checksum. Restore the common license file to its canonical content, or update the checksum in the recipe:

Terminal window
md5sum ${COMMON_LICENSE_DIR}/Apache-2.0
# Update LIC_FILES_CHKSUM in soc-ota-agent_1.0.0.bb to match

soc-ota-agent.service: Failed to start — can't open /etc/otapulse/otapulse.conf

The configuration file was not generated during the build. This usually means OTA_SERVER_URL was not set in local.conf when the recipe ran, so the template substitution produced an empty or invalid file. Set the variable and do a clean rebuild:

Terminal window
bitbake -c cleanall soc-ota-agent
bitbake soc-ota-agent

OTA update fails with “signature verification failed” after flashing a new artifact

Either the public key in the image does not match the private key used to sign the artifact, or SOC_OTA_SIGNATURE_VERIFICATION is set to "1" but signing-keys was not included in IMAGE_INSTALL. Confirm both:

Terminal window
# On device — check keys are present
ls -la /etc/soc-monitoring/signing-keys/active/
# In your build — check both packages were included
bitbake -e soc-monitoring-image | grep '^IMAGE_INSTALL'

If the key files are missing, add signing-keys to IMAGE_INSTALL:append and rebuild.