What is Recovery Partition Update Scheme-Free Linux Device Drivers Course

PREV_LEC | NEXT_LEC

Recovery Partition Update Scheme
A dedicated recovery OS as a robust alternative to A/B updates — part of our free Linux kernel development course

Recovery Partition Update Scheme

If you’ve followed our free embedded systems course, you already know that atomic firmware updates matter because a power failure mid-update should never leave a device unbootable. In the previous lecture we looked at the dual-copy A/B scheme. This lecture covers a second pattern that’s just as common in real products: a dedicated recovery partition that does the update work instead of the main OS. This approach is a core topic in our free linux kernel development course because it shows up constantly in Android-derived and consumer embedded devices.

recovery partition firmware update boot flag embedded linux U-Boot environment ramdisk updater

What You Will Learn

  • Why a recovery partition scheme exists alongside A/B updates
  • How the boot flag decides which OS runs on the next boot
  • The lifecycle of a recovery-driven update, start to finish
  • How to size a recovery partition realistically
  • A minimal, original recovery updater you can build and boot yourself
  • Where this pattern is used in real products, and its trade-offs against A/B updates

Prerequisites

  • Comfort with U-Boot environment variables and the boot flow (covered in our bootloader course)
  • A basic grasp of root filesystems and initramfs/ramdisk concepts
  • Familiarity with the dual-copy A/B update scheme from the previous lecture in this free linux device drivers course

Why a Separate Recovery OS?

The dual-copy A/B scheme keeps two full copies of the main OS and switches between them. That works well, but it assumes the main OS itself is trustworthy enough to perform its own update. A recovery partition scheme takes a different stance: never let the OS that’s about to be replaced be the one doing the replacing. Instead, a small, independent, rarely-changing recovery OS handles the actual write operation. If the main OS is corrupted, missing, or compromised, the recovery OS is still there, untouched, ready to fix things.

This is the model many Android devices use in practice. The main OS image can be several hundred megabytes, but the recovery OS is typically only a few megabytes, because its only job is to run an updater — it doesn’t need a windowing system, a package manager, or most of the drivers the main OS carries.

Partition Layout
[ bootloader ] [ boot-flag env ] [ recovery OS (small) ] [ main OS (large) ] [ data ]

The Update Lifecycle

The sequence has four clean stages, and each one is designed to be safely interruptible:

  1. Stage the update. The new image (or delta) is written to a spare area or downloaded to the data partition, but nothing about the running system changes yet.
  2. Set the boot flag. A single environment variable (or a small flag block) is written telling the bootloader “boot the recovery OS next time, not the main OS.”
  3. Reboot into recovery. The recovery OS starts, runs the updater, and overwrites the main OS partition(s) with the new image.
  4. Clear the flag and reboot again. Once the updater finishes successfully, it clears the boot flag and reboots. The bootloader now boots the freshly-updated main OS.

The important safety property: if power is lost at any point during stage 3, the boot flag is still set, so the device reboots straight back into the recovery OS and simply resumes or retries the update. It can never boot into a half-written main OS, because the bootloader only looks at the flag — never at the state of the main partition.

Setting the Boot Flag with U-Boot

On a U-Boot based board this is usually nothing more than an environment variable checked by the boot script:

\# from a running Linux userspace, using fw_setenv
fw_setenv ep_bootmode recovery

\# U-Boot's boot script (simplified)
if test "${ep_bootmode}" = "recovery"; then
    run bootcmd_recovery
else
    run bootcmd_main
fi

The recovery updater clears the flag the same way once it’s done:

fw_setenv ep_bootmode main
reboot

Sizing the Recovery Partition

ComponentTypical sizeNotes
Recovery kernel3–6 MBSame kernel family as main OS, minimal config
Recovery ramdisk/rootfs2–8 MBBusyBox + updater binary + a handful of libraries
Update staging areaSize of one main OS imageOften placed on the data partition, not the recovery partition itself

Keeping the recovery OS this small is what makes the whole scheme cheap: you’re duplicating only a few megabytes, not the full main OS, so the storage overhead of “always having a fallback” stays low even on constrained NAND/eMMC parts.

A Minimal Original Updater

Here’s a small, original updater shell script you can adapt — it’s deliberately simple so the logic stays visible. It assumes the new image has already been staged at /data/update.img and the main OS lives on /dev/mmcblk0p2:

#!/bin/sh
# ep_updater.sh - minimal recovery-side updater (original example)

set -e

STAGED_IMAGE="/data/update.img"
MAIN_PARTITION="/dev/mmcblk0p2"

echo "ep_updater: verifying staged image"
sha256sum -c "${STAGED_IMAGE}.sha256"

echo "ep_updater: writing new main OS image"
dd if="${STAGED_IMAGE}" of="${MAIN_PARTITION}" bs=4M conv=fsync

echo "ep_updater: clearing boot flag"
fw_setenv ep_bootmode main

echo "ep_updater: update complete, rebooting"
sync
reboot

Building a recovery ramdisk that runs this script as its init is the same initramfs process covered in our root filesystem lecture — the only difference is that init here runs the updater instead of switching to the main rootfs.

\# expected console output on a successful recovery boot
ep_updater: verifying staged image
update.img: OK
ep_updater: writing new main OS image
41943040+0 records in
41943040+0 records out
ep_updater: clearing boot flag
ep_updater: update complete, rebooting

Recovery Partition vs A/B Updates

AspectRecovery partitionDual-copy A/B
Storage overheadLow — only a few MB for recoveryHigh — a full spare copy of the main OS
Update path trustNever uses the OS being replacedRelies on the currently booted OS to write the inactive slot
Downtime during updateTwo reboots, device offline during recoveryCan often update the inactive slot in the background
ComplexityLower — one flag, one small OSHigher — slot bookkeeping, boot-success confirmation logic

Real-World Use Cases

  • Android and Android-derived embedded products (historically, before seamless A/B became common)
  • Set-top boxes and routers where storage is tight and a background-updated spare copy isn’t affordable
  • Field devices where “never trust the thing you’re replacing” is a hard safety requirement

Common Mistakes and Troubleshooting

  • Forgetting to clear the flag. If the updater crashes before clearing ep_bootmode, the device loops into recovery forever — always clear the flag as the very last step, after the write is confirmed.
  • No image verification. Writing an unverified image straight to the main partition turns a network glitch into a bricked device. Always checksum or sign the staged image before writing.
  • Recovery OS depends on the main OS. If recovery shares a filesystem or driver blob with the main partition, corruption there can take recovery down too — keep it fully independent.
  • No fsync/conv=fsync on the write. Without forcing a sync, a power loss right after dd “finishes” can still leave data in cache, not on flash.

Best Practices

  • Treat the recovery OS as read-mostly firmware — update it rarely and test it exhaustively when you do.
  • Always verify a cryptographic checksum (or signature) of the staged image before writing.
  • Log update attempts to a persistent area so field diagnostics don’t require physical access.
  • Test the power-loss-during-update path explicitly — pull power mid-dd in your CI/QA rig, don’t just assume the flag logic works.

Performance and Security Considerations

Performance is rarely the bottleneck here — the write itself is a bounded, sequential operation. Security is the bigger concern: because the recovery OS has unrestricted write access to the main partition, it must verify the staged image’s signature, not just its checksum, or an attacker who can plant a file in the staging area can flash arbitrary firmware. Keep the recovery OS’s own image itself protected by secure boot if your SoC supports it.

Summary and Key Takeaways

  • A recovery partition scheme separates “the OS that runs” from “the OS that updates,” which removes an entire class of self-update failure.
  • The boot flag is the single source of truth for what boots next — keep clearing it the very last step.
  • Recovery OS size stays small (a few MB), keeping the storage overhead of this scheme low.
  • Compared to A/B updates, this scheme trades background-update convenience for simplicity and a stronger trust boundary.

This wraps up our look at atomic update strategies in this free linux kernel development course. Together with the dual-copy A/B lecture, you now have two field-proven patterns to choose between when designing an update mechanism for your own embedded Linux product.

FAQ

What’s the difference between a recovery partition and an A/B scheme?

A recovery partition uses one small, independent OS whose only job is to write updates to a single main partition. A/B keeps two full copies of the main OS and switches which one boots. Recovery-based schemes use less storage; A/B schemes usually allow background updates with less downtime.

Why does Android use a recovery partition?

Historically, Android devices had limited flash storage, so keeping a full spare copy of the main OS wasn’t affordable. A small recovery OS gave a safe, independent updater while keeping storage overhead low.

What happens if power is lost while the recovery OS is writing the update?

The boot flag is still set to “recovery,” so the device boots back into the recovery OS on the next power-up and can retry or resume the write. It never boots into a half-written main OS.

How big should a recovery partition be?

Typically a few megabytes — just enough for a minimal kernel, a small ramdisk with BusyBox, and the updater binary. It doesn’t need the drivers or services the main OS carries.

Can I combine a recovery partition with A/B updates?

Yes. Some products use a recovery OS as the trusted writer, but write to an inactive A/B slot instead of a single main partition, combining the trust boundary of recovery-based updates with the rollback flexibility of A/B.

Does the recovery OS need its own kernel?

Usually yes — a small, separate kernel build keeps recovery fully independent of anything that might be broken in the main OS’s kernel image.

How do I test this update path safely?

Build a QA rig that can cut power at random points during the write step and confirm the device always recovers. This is the single most important test for any atomic update scheme.

Want to build a full update pipeline?

Follow along with our free Linux kernel and embedded Linux courses on EmbeddedPathashala for hands-on driver and storage lectures.

Browse the Free Course Join the Community

PREV_LEC | NEXT_LEC