Boot and Provisioning

Firmware selects the boot path, initramfs prepares runtime storage, and the selected rootfs starts systemd. First boot also populates the release slots; subsequent boots reuse the provisioned volumes and persistent state.

Boot Flow

Firmware selects a boot slot and starts the kernel and initramfs. Early userspace activates storage. First boot installs the seed bundle and reboots; normal boot mounts the selected rootfs, prepares the etc overlay, and starts systemd services and applications. Firmware selects a boot slot and starts the kernel and initramfs. Early userspace activates storage. First boot installs the seed bundle and reboots; normal boot mounts the selected rootfs, prepares the etc overlay, and starts systemd services and applications.

Reference rootfs-on-LVM startup. First-boot bundle installation takes a separate path and reboots; normal startup continues to the selected system. Optional storage encryption is unlocked before LVM is used.

Booting Process on EIG Hardware

The BSP signing features select signed bootloader and kernel artifacts. HAB4 applies to the i.MX8M EIG platforms; AHAB applies to EIGXS/i.MX93. A provisioned device anchors verification in its matching fused trust material and secure lifecycle state. An unfused development device is not equivalent to an authenticated production boot chain.

EIG-M / EIG-M-DIN / EIG-MA (HAB4)
  ROM -> authenticated boot container / U-Boot
      -> signed kernel boot path -> initramfs -> selected rootfs

EIG-XS (AHAB)
  ROM / ELE -> authenticated boot container / U-Boot
            -> signed OS container [kernel + DTB + initramfs]
            -> selected LVM rootfs

On EIGXS, INITRAMFS_IMAGE_BUNDLE = "0" because the initramfs is a separate image inside the signed AHAB OS container. AHAB_INCLUDE_INITRAMFS controls its inclusion. The board describes the container image layout and load addresses through AHAB_OS_CONTAINER_CONFIG. The signing-data directory supplies the selected keys and signing configuration through SIG_DATA_PATH.

Do not infer rootfs authentication or encrypted boot from kernel signing. The reference RAUC verity bundle format verifies an update bundle; it does not by itself enable dm-verity on the running root filesystem. Storage confidentiality, when selected, is supplied by Extended Security. For signing material, SRK programming, and device closing, see Signing Keys Generation.

U-Boot Environment Protection

The reference EIG-M, EIG-M-DIN, EIG-MA, and EIG-XS manifests enable uboot-hardened by default. The common i.MX KAS configuration includes the BSP’s ci/fragments/hardened.yml, which selects the hardened U-Boot configuration without an additional extension layer.

U-Boot first loads its compiled-in environment, then accepts only explicitly allowed overrides from the saved environment. This provides a read-only baseline for persistent boot policy, including bootcmd, while keeping the state needed for A/B updates writable. For the default A/B slot names, the writable overrides are:

Writable U-Boot update state

Variable

Flags

Purpose

BOOT_ORDER

sw: string, writable

Preferred slot order.

BOOT_A_LEFT

dw: decimal, writable

Remaining boot attempts for slot A.

BOOT_B_LEFT

dw: decimal, writable

Remaining boot attempts for slot B.

The BSP defines this list in ENV_FLAGS_LIST and compiles it through CONFIG_HARDENED_ENV_FLAGS_LIST_STATIC. Its hardened.cfg.in enables CONFIG_ENV_WRITEABLE_LIST and CONFIG_ENV_APPEND so that loading saved state preserves the built-in baseline. CONFIG_ENV_ACCESS_IGNORE_FORCE prevents the force option from bypassing environment access checks.

Protection applies to values imported from persistent storage. Boot commands continue to set temporary variables in RAM, and the environment storage remains writable so that U-Boot and RAUC can save slot order and retry counters. A value written to storage outside the allowlist does not override the protected default when U-Boot reloads the environment. Changes to protected boot policy are delivered through an updated bootloader build.

This policy applies to the hardened EIG configuration. The reference QEMU U-Boot manifests do not select uboot-hardened; the QEMU UEFI configuration uses EFI variables for slot selection. Environment protection and device secure-boot enforcement are separate mechanisms; see OrchestraOS Security Architecture.

Initramfs and Userspace Handoff

The OrchestraOS initramfs mounts the provisioning filesystem, grows the storage partition when required, and creates or activates the logical volumes. Feature layers can prepare an encrypted backing device before the shared LVM modules run. The first-boot population step installs the seed bundle before normal operation begins.

Once the selected rootfs is mounted, its pre-init wrapper prepares the persistent /etc overlay before invoking systemd. Runtime mount units select the matching /app and /boot filesystems. Applications must start after any mounts they require. The overlay directories and persistence policy are described in Persistent /etc Overlay.

First-Boot Provisioning

A rootfs-on-LVM disk image carries a RAUC bundle in its first boot partition. The early boot flow populates the runtime logical volumes from that bundle; copying the WIC to a disk does not itself create populated rootfs logical volumes.

.lvm_created.done on /data-unencrypted records completed LVM creation. A separate .lvm_populate.done records completed bundle installation. These markers have different purposes and must not be treated as interchangeable. A creation marker with an unreadable volume group causes recovery to stop rather than reinitialize storage. The Initramfs LVM Policy Hooks allow feature layers to place additional guards around growth, initialization, and cleanup.

The population module locates boot_A on ORCOS_DISK_DEVICE, finds a .raucb seed bundle there, and fails if none is available. In the U-Boot reference flow, installation populates the other slot and reboots into it. In the EFI flow, the bundle is first staged off the boot partition, RAUC provisions the first slot, and EFI entries are created for A and B. Initial EFI BootOrder selects A; subsequent boots maintain the entries without unconditionally resetting the active slot selection.

EFI slot entries include each rootfs device and rauc.slot argument. The VM’s writable firmware variable store must persist between boots. Recreating it loses boot entries and selection state; see Virtual Platforms.

Subsequent Boots

After provisioning, initramfs activates existing storage and skips creation or population according to the completion markers. RAUC installs later updates into the inactive slot group. U-Boot tracks BOOT_ORDER and BOOT_A_LEFT / BOOT_B_LEFT with three attempts by default, decrements an attempt before boot, and falls back when the selected slot has no attempts left. EFI uses its own RAUC backend and firmware selection state; the U-Boot retry counter description does not apply to that backend.

Project health policy and persistent-state compatibility are covered in RAUC Update Flow.

Initramfs LVM Policy Hooks

The initramfs-module-lvm-grow and initramfs-module-lvm-create packages own partition growth, LVM creation, filesystem initialization, and the completion marker. Optional packages can add policy files without replacing these packages, their files, or their shell functions.

initramfs-framework-orchestra advertises LVM_HOOKS_API = "1". LVM_HOOKS_DIR defaults to /etc/lvm-hooks.d. Files in each event directory are sourced in filename order in the initramfs shell:

LVM policy events

Event

When it runs

Policy control

before-grow

After detecting a misplaced GPT backup header, before changing the disk

Abort if growth is unsafe

before-create

Before inspecting or initializing the configured LVM device

Validate storage; optionally set LVM_CREATE_WIPE_SIGNATURES=0

before-cleanup

Before destructive LVM cleanup, including failure recovery

Set LVM_CLEANUP_ALLOWED=0 to preserve storage

The two policy flags default to 1 for each operation. With no hook files, signature removal and cleanup retain their existing behavior. Existing volume groups with .lvm_created.done continue to skip initialization. No disk format, volume name, or completion-marker path changes are required. If the completion marker exists but the volume group cannot be read, boot stops for recovery instead of attempting to initialize storage again.

Hooks must explicitly check command failures and call lvm_fail when an operation must not continue. Returning a nonzero status from a sourced hook also aborts boot. lvm_fail exits even if fatal returns, preventing the failed operation from continuing. Hooks share shell state, so use a feature-specific prefix for their own variables and functions.

For example, a project-specific storage policy package can install:

# /etc/lvm-hooks.d/before-cleanup/10-storage-policy
LVM_CLEANUP_ALLOWED=0

The base modules still perform the LVM operations. They handle command failures explicitly and flush initialized storage before persisting the completion marker. Feature layers prepare their storage device before 08-lvm_create and supply any additional policy guards. Extension-specific implementation and configuration are documented in the respective layer’s README.md.