Skip to content

Bootloader mode variables and build checks

This page lists every variable you set for bootloader compatibility mode. You set them in conf/local.conf. They only apply when OTAPULSE_BOOT_MODE is bootloader. In native mode they have no effect.

A complete example is in meta-otapulse/conf/samples/local.conf.bootloader.sample in the OTA-Pulse source tree.

VariableValuesMeaning
INHERIT += "otapulse-full"Turns the mode switch on. It must be a build-wide INHERIT in local.conf. An inherit line in a recipe is too late.
OTAPULSE_BOOT_MODEnative (default), bootloaderbootloader selects this mode.
OTAPULSE_BOOTLOADERuboot, grubWhich bootloader environment holds the slot flag. There is no default.
OTA_SERVER_URLURLYour OTA-Pulse server, as in native mode.
VariableDefaultMeaning
OTAPULSE_IMAGE_TYPEsd for uboot, uefi for grubsd: an MBR disk image for U-Boot boards. uefi: a UEFI disk image that boots through GRUB. gpt: accepted with both bootloaders. We have not tested gpt.
OTAPULSE_STORAGE_DEVICEboard support defaultThe block device that holds the partitions, for example /dev/mmcblk0 or /dev/vda. Set it explicitly.
OTAPULSE_STORAGE_TOTAL_SIZE_MBboard support defaultThe size of the medium the image is written to. The two root file system partitions get what is left after the boot partition, the data partition and a small overhead.
OTAPULSE_BOOT_PART_SIZE_MBboard support defaultSize of the boot (FAT) partition. The sample uses 16.
OTAPULSE_DATA_PART_SIZE_MBboard support defaultSize of the persistent /data partition. The sample uses 128.
OTAPULSE_SWAP_PART_SIZE_MBboard support defaultSwap partition size. 0 means none.
OTAPULSE_GROW_DATA_PART11: on every boot the data partition is extended to the end of the medium and its file system is grown, before the agent starts. 0 keeps the size the image was built with.
OTAPULSE_DEVICE_TYPEderived from MACHINE by the board supportThe device type that artifacts are checked against.

Default 10. The number of seconds before a panicking kernel resets the board. The bootloader adds panic=<n> to the kernel command line (U-Boot through its boot commands, GRUB through the generated boot configuration). The value must be a positive whole number. 0 or a negative number is refused.

Why it matters: the bootloader’s boot counter only turns over when the board resets. A kernel that panics without a timeout hangs forever. The bad update is then never rolled back.

You can verify the value on a running device:

Terminal window
cat /proc/cmdline

On the qualified images the command line contained panic=7, because those images were built with OTAPULSE_PANIC_TIMEOUT_S = "7". The console then printed Rebooting in 7 seconds on a panic.

These variables describe where your U-Boot keeps its environment. Leave them unset to use the layout of the board support. Set them when your board’s U-Boot already keeps the environment somewhere else. The build compares them with U-Boot’s own configuration and stops on a mismatch.

VariableDefaultMeaning
OTAPULSE_UBOOT_ENV_OFFSETboard support layoutByte offset on the storage device of the first copy of the environment.
OTAPULSE_UBOOT_ENV_OFFSET_REDUNDboard support layoutByte offset of the second (redundant) copy. It must be at least OTAPULSE_UBOOT_ENV_SIZE bytes away from the first.
OTAPULSE_UBOOT_ENV_SIZE0x20000Size in bytes of one environment copy.
OTAPULSE_UBOOT_AUTO_CONFIGURE11: OTA-Pulse adds the boot counter and the redundant environment to U-Boot’s configuration. 0: your U-Boot already has them, and the build checks that it does.

The three numbers are byte counts in decimal or 0x hexadecimal. They must be positive multiples of 512. The environment must be redundant. Without a second copy a power cut while the environment is written leaves the device unable to boot or to roll back.

These four variables are refused when OTAPULSE_BOOTLOADER is grub.

VariableDefaultMeaning
OTAPULSE_ALLOW_GRUB_DEBUG0With 0, a GRUB image built with the board support’s debug options (force-grub-prompt or debug-pause) is refused. Those options stop an unattended device at a GRUB prompt. 1 is a developer-only opt-out. Never ship that image.
VariableDefaultMeaning
OTAPULSE_PROVISIONING_TOKENemptyThe fleet provisioning token. Only letters, digits, underscore, dot and dash are accepted.
OTAPULSE_PROVISIONING_MODEbakedbaked: the token is written into the image, and therefore into every update artifact built from it, so build updates with an empty token or use manual. manual: the image carries no token file and you place /data/otapulse/provision.env on each device.

See Provisioning for both paths, the security notes, and what the monitoring daemon needs.

VariableDefaultMeaning
OTAPULSE_GENERATE_ARTIFACT1Every image build also writes the .otapulse rootfs artifact. 0 builds the disk image only.
SOC_OTA_SIGNATURE_VERIFICATION, SOC_OTA_SIGNING_KEYSignature verification and signing, as in native mode. Use them for production.

A misconfiguration fails the build with a message that names the variable to fix. The checks run as early as the answer exists. A message that carries a dagger (†) came from a real BitBake run during our qualification. The others are written in the class and covered by unit tests.

You can run this part alone with bitbake -p.

SituationMessage beginsWhat to do
Unknown mode †OTAPULSE_BOOT_MODE must be "native" or "bootloader"Fix the value.
No or unknown bootloader †OTAPULSE_BOOT_MODE = "bootloader" requires OTAPULSE_BOOTLOADER to be "uboot" or "grub"Set OTAPULSE_BOOTLOADER.
Unknown image type †OTAPULSE_IMAGE_TYPE must be "sd", "uefi" or "gpt"Fix the value.
Image type does not fit the bootloader †OTAPULSE_IMAGE_TYPE = "uefi" ... cannot be combined with OTAPULSE_BOOTLOADER = "uboot" (and the same the other way round)Pair uboot with sd and grub with uefi.
Support layers missing †OTAPULSE_BOOT_MODE = "bootloader" requires the OTA-Pulse bootloader support layers, but your BBLAYERS is missing: ...Add the named layers to bblayers.conf.
Panic timeout not positive †OTAPULSE_PANIC_TIMEOUT_S must be a positive number of secondsUse a whole number of 1 or more.
Provisioning mode unknownOTAPULSE_PROVISIONING_MODE must be "baked" or "manual"Use one of the two.
Token has invalid charactersOTAPULSE_PROVISIONING_TOKEN contains characters that are not valid in a provisioning tokenCopy the token again from the console. The value is never printed.
OTAPULSE_GROW_DATA_PART not 0 or 1OTAPULSE_GROW_DATA_PART must be "1" or "0"Fix the value.
Mode enabled from a recipeotapulse-full is enabled in bootloader mode from a recipe (inherit), which is too lateUse INHERIT += "otapulse-full" in local.conf.
U-Boot variable on a GRUB build †OTAPULSE_UBOOT_ENV_OFFSET only applies to OTAPULSE_BOOTLOADER = "uboot"Remove the U-Boot variables.
U-Boot number not valid †OTAPULSE_UBOOT_ENV_SIZE must be a positive number of bytes that is a multiple of 512Give bytes, multiple of 512.
OTAPULSE_UBOOT_AUTO_CONFIGURE not 0 or 1 †OTAPULSE_UBOOT_AUTO_CONFIGURE must be "1" ... or "0"Fix the value.
Environment not redundant †The U-Boot environment is not redundant: both copies are at offset ...Set OTAPULSE_UBOOT_ENV_OFFSET_REDUND to a second offset.
Environment copies overlap †The two U-Boot environment copies ... overlapMove the second copy at least OTAPULSE_UBOOT_ENV_SIZE away.
Copy outside the reserved area †The second U-Boot environment copy ... lies outside the area reserved for the environmentMove it inside the area, or leave it unset.
Two copies too large †Two copies of the U-Boot environment of OTAPULSE_UBOOT_ENV_SIZE = ... need ...Reduce OTAPULSE_UBOOT_ENV_SIZE.
Offset not on the partition grid †OTAPULSE_UBOOT_ENV_OFFSET (...) must be a multiple of the partition alignmentUse a multiple of the alignment named in the message.
GRUB debug option †The GRUB boot configuration is built with the debug option ...Remove it from PACKAGECONFIG.
GRUB debug option, opted out †Warning: OTAPULSE_ALLOW_GRUB_DEBUG = "1": ... must NEVER be shippedUse only for a developer image.
State scripts not gated †OTAPULSE_BOOT_MODE = "bootloader": the state scripts of the agent recipe are not safe for bootloader modeUpdate your meta-otapulse layer.
GRUB panic support missing †OTAPULSE_BOOTLOADER = "grub": the GRUB boot configuration recipe does not carry the OTA-Pulse kernel panic timeout supportUpdate your meta-otapulse layer.

These run several minutes into a build, when U-Boot’s configuration and compiled-in environment exist. bitbake -p does not run them.

SituationMessage beginsWhat to do
No boot counter †OTAPULSE_UBOOT_AUTO_CONFIGURE: The U-Boot configuration built for this image does not enable CONFIG_BOOTCOUNT_LIMIT and CONFIG_BOOTCOUNT_ENVEnable the boot counter, or set OTAPULSE_UBOOT_AUTO_CONFIGURE = "1".
Environment not on MMC or SD... does not keep its environment on the MMC/SD storage (CONFIG_ENV_IS_IN_MMC is not set)Move the environment to MMC or SD.
Not redundant in U-Boot’s configurationThe U-Boot environment in the U-Boot configuration built for this image is not redundantMake U-Boot’s environment redundant.
Environment size or offset differs †OTAPULSE_UBOOT_ENV_SIZE: U-Boot's configuration has CONFIG_ENV_SIZE = ..., but the agent is configured to use ... (same for the offset variables)Set the variable to the value your U-Boot uses.
Wrong MMC device †OTAPULSE_STORAGE_DEVICE: U-Boot's configuration keeps its environment on MMC device ...Set OTAPULSE_STORAGE_DEVICE to the device your U-Boot uses.
Panic timeout dropped by your boot commands †OTAPULSE_PANIC_TIMEOUT_S: The kernel command line that U-Boot passes when it runs bootcmd ... does not contain panic=Do not replace or reset the kernel command line in your own U-Boot commands.
No bootlimit, upgrade_available or altbootcmd in the compiled environmentThe compiled-in U-Boot environment has no positive bootlimit ...Enable the boot counter and rollback commands.
Generated GRUB configuration sets panic=0 †OTAPULSE_PANIC_TIMEOUT_S: the generated GRUB boot configuration sets panic=0Remove the override.
Boot script drops the panic timeout, or has a fixed root= (boards that boot through a boot script) †The kernel command line that the image's boot script hands to the kernel ... or The firmware command line (cmdline.txt) has a fixed root=...Keep the board support’s boot script and cmdline.txt.
SituationMessage beginsWhat to do
Boot mode marker missing or wrong †OTAPULSE_BOOT_MODE: The image does not contain /etc/otapulse/boot_mode = bootloaderInstall the agent (soc-ota-agent) in the image, built in bootloader mode.
Update scripts missing or ungatedThe image does not contain the state script ... or The image's state script ... Update your meta-otapulse layer and rebuild the agent.
U-Boot environment description missing or not redundantThe image does not contain /data/u-boot/fw_env.config or ... describes 1 environment copy, not twoCheck OTAPULSE_BOOTLOADER and OTAPULSE_UBOOT_ENV_OFFSET.

Some checks mention names that come from the open-source board support, such as variables and recipe names. Those messages are listed under Names you may see in build logs and on devices.

  • The boot counter, environment layout and panic timeout checks run when U-Boot is configured or compiled. A build can fail minutes in, not at parse time.
  • Boards where U-Boot builds several configurations (UBOOT_CONFIG) are covered by unit tests only. We have not built one.
  • The kernel command line of a boot script is checked only when the image’s boot partition is built by the sdimg step and contains a boot.scr. That is the Raspberry Pi 4 case. For other boards that start the kernel from a script, check /proc/cmdline on the device.
  • The early check of the MMC device can only name OTAPULSE_STORAGE_DEVICE when the environment sits in the wrong MMC hardware partition. The real fix may be in your U-Boot configuration.
  • A passing build does not prove a rollback. Qualify the board with the qualification guide.