.. _os-architecture-boot: ##################### 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 ========= .. figure:: images/orchestraos-boot.svg :alt: 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. :width: 100% :class: architecture-figure 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. .. _os-booting-process-nxp: 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. .. code-block:: text 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 :ref:`os-extended-security`. For signing material, SRK programming, and device closing, see :ref:`os-signing-keys`. .. _os-uboot-environment: 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: .. list-table:: Writable U-Boot update state :header-rows: 1 * - 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 :ref:`os-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 :ref:`os-etc-overlay`. .. _os-first-boot: 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 :ref:`os-initramfs-lvm-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 :ref:`os-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 :ref:`os-rauc-update-flow`. .. _os-initramfs-lvm-hooks: 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: .. list-table:: LVM policy events :header-rows: 1 * - 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: .. code-block:: sh # /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``.