U-Boot environment overview
Peridiod uses the U-Boot environment as persistent storage for update state tracking and optional device identity credentials. The U-Boot environment provides atomic writes and survives firmware updates, making it ideal for critical device state that must persist across A/B partition switches and recovery scenarios.
How peridiod interacts with U-Boot environment
Peridiod accesses the U-Boot environment by directly reading and writing to block devices at specific byte offsets. The daemon uses /etc/fw_env.config
to determine the storage location, which typically specifies a device path (like /dev/mmcblk0
), byte offset, and environment size.
This follows the standard U-Boot environment format and configuration pattern documented in the U-Boot Environment Variables specification. The /etc/fw_env.config
file format is defined in the U-Boot source - see the example configuration at tools/env/fw_env.config and documentation at tools/env/README
.
Direct block device access
The daemon performs raw binary I/O operations on the storage device:
- Reads the entire environment block from the specified device offset
- Validates data integrity using CRC32 checksums
- Caches key-value pairs in memory for fast access
- Writes updated data back to the same location with proper CRC calculation
This approach is equivalent to what the standard U-Boot tools fw_printenv
and fw_setenv
do, but implemented directly in the daemon without external process spawning.
Environment block format
The U-Boot environment uses a binary format as specified in the U-Boot documentation with:
- 4-byte CRC32 checksum at the beginning for integrity verification
- Optional redundancy byte for dual-bank environments
- Null-terminated key=value pairs stored as ASCII strings
- Padding bytes (0xFF) to fill the allocated block size
Data constraints include:
- No NULL characters (
\0
) within keys or values - No equals signs (
=
) in keys - Values may contain embedded newlines
- ASCII encoding recommended for compatibility with U-Boot and other tools
Redundant environments
Many systems use redundant U-Boot environments for fault tolerance:
- Two identical blocks stored at different offsets
- Generation counters track which block is newer
- Atomic updates by writing to the inactive block first
- Automatic failover if one block becomes corrupted
State tracking
Peridiod maintains comprehensive update metadata to enable recovery from interrupted updates, provide rollback capabilities, and track update history:
Firmware slot management
The system tracks active and previous firmware slots using prefixed keys:
peridio_active
- currently active firmware slot ("a" or "b")a.peridio_*
- metadata for firmware slot Ab.peridio_*
- metadata for firmware slot B
Update progress tracking
During updates, peridiod stores progress information:
peridio_via_progress
- release PRN being installedperidio_bun_progress
- bundle PRN being installedperidio_vsn_progress
- version being installedperidio_bin_progress
- binary being installedperidio_bc_progress
- boot count for rollback detection
Current and previous state
After successful updates, progress values are promoted to current state:
peridio_via_current/previous
- current and previous release PRNsperidio_bun_current/previous
- current and previous bundle PRNsperidio_vsn_current/previous
- current and previous versionsperidio_bin_current/previous
- current and previous binary identifiers
System configuration
The daemon also reads system information from the environment:
peridio_disk_devpath
/nerves_fw_devpath
- device paths for installationperidio_uuid
/nerves_fw_uuid
- device identifiers- Application partition paths and filesystem types
Device identity storage
Device identity credentials can optionally be stored in the U-Boot environment rather than the filesystem. The daemon can load PEM-encoded certificates and private keys from environment variables, with optional Base64 decoding support.
Example configuration:
key_pair_source: "uboot-env",
key_pair_options: %{
"private_key" => "device_private_key",
"certificate" => "device_certificate"
}
While hardware security modules (HSMs) or secure elements are preferred for production deployments, U-Boot environment storage enables provisioning workflows where credentials are injected during manufacturing and must remain accessible before filesystem initialization or survive factory resets.
Storage considerations
The U-Boot environment typically resides on flash storage with limited write cycles. Peridiod minimizes writes by:
- Only updating variables when values actually change
- Batching multiple updates into single write operations
- Caching values in memory to avoid repeated reads
High-frequency update deployments should consider the write endurance characteristics of their storage medium. Loss of this data can require device re-provisioning and affect update recovery capabilities.
The environment block location and size are configured in /etc/fw_env.config
, which specifies the device path, offset, and size of the environment storage area.