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
| Release | Compatible |
|---|---|
| Kirkstone (4.0 LTS) | Yes |
| Langdale (4.1) | Yes |
| Mickledore (4.2) | Yes |
| Nanbield (4.3) | Yes |
| Scarthgap (5.0 LTS) | Yes |
| Earlier releases | Not 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
-
Clone the repository
From the directory that contains
poky/andmeta-openembedded/:Terminal window git clone https://github.com/intronix/socMonitoring.gitThe Yocto layer lives at
ota-pulse/meta-otapulse/inside the cloned repository. -
Add the layer to
bblayers.confEdit
conf/bblayers.confin your build directory. Appendmeta-otapulseandmeta-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 usebitbake-layers add-layerto 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 imageIMAGE_INSTALL:append = " soc-ota-agent signing-keys"
# Systemd is required by the layerDISTRO_FEATURES:append = " systemd usrmerge"INIT_MANAGER = "systemd"
# OTA-Pulse server URL — the agent posts here during updatesOTA_SERVER_URL = "https://your-server.example.com"
# --- Optional: signature verification ---
# Set to "1" to enable artifact signature verification on-deviceSOC_OTA_SIGNATURE_VERIFICATION = "0"
# Path where signing-keys recipe installs public keysSOC_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:
| Partition | Label | Size | Purpose |
|---|---|---|---|
/boot | boot | 100 MB | FAT32, kernel + DTB |
/ | rootfs-a | 1 GB | Primary root filesystem |
| (unmounted) | rootfs-b | 1 GB | Inactive slot for OTA writes |
/data | data | 500 MB | Persistent 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:
# Copy your exported public keys into the layercp ~/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
source poky/oe-init-build-env buildbitbake soc-monitoring-imageOr, if you are extending your own image recipe:
bitbake <your-image-recipe>The built WIC image lands in tmp/deploy/images/<MACHINE>/. Flash it to your device:
sudo dd if=tmp/deploy/images/<MACHINE>/soc-monitoring-image-<MACHINE>.wic \ of=/dev/sdX bs=4M status=progresssyncAfter boot, verify the agent started successfully:
ssh root@<device-ip>systemctl status soc-ota-agentjournalctl -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-layers — meta-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:
bitbake-layers add-layer /path/to/ota-pulse/meta-otapulseERROR: 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:
md5sum ${COMMON_LICENSE_DIR}/Apache-2.0# Update LIC_FILES_CHKSUM in soc-ota-agent_1.0.0.bb to matchsoc-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:
bitbake -c cleanall soc-ota-agentbitbake soc-ota-agentOTA 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:
# On device — check keys are presentls -la /etc/soc-monitoring/signing-keys/active/
# In your build — check both packages were includedbitbake -e soc-monitoring-image | grep '^IMAGE_INSTALL'If the key files are missing, add signing-keys to IMAGE_INSTALL:append and rebuild.