॥ श्री ॥

Boot Process

Architecture 2026-05-13

Shanios uses a fully measured, signed boot chain built on systemd-boot, dracut-generated Unified Kernel Images (UKIs), and optionally TPM2 + Secure Boot verification.

Boot Chain Overview

UEFI Firmware
  └─ systemd-boot (EFI binary at /boot/efi/EFI/BOOT/BOOTX64.EFI via shim)
       └─ UKI: shanios-blue.efi  or  shanios-green.efi
            ├─ Linux kernel
            ├─ initramfs (dracut)
            ├─ kernel command line (embedded — tamper-evident)
            └─ OS stub (systemd-stub)
                  └─ dracut initrd
                       ├─ LUKS2 unlock (passphrase or TPM2 auto-unlock)
                       ├─ @data mount (for boot failure + /etc overlay)
                       ├─ boot_hard_failure marker written (pre-mount hook)
                       ├─ Btrfs root mount (@blue or @green, read-only)
                       ├─ OverlayFS /etc mount (pre-pivot hook)
                       ├─ boot_hard_failure cleared on success (pre-pivot hook)
                       └─ Switch root → systemd PID 1

Unified Kernel Images (UKIs)

Each slot has its own UKI — a single EFI PE binary that bundles the kernel, initramfs, and kernel cmdline together:

| File | Slot | |------|------| | /boot/efi/EFI/Linux/shanios-blue.efi | @blue | | /boot/efi/EFI/Linux/shanios-green.efi | @green |

UKIs are generated by gen-efi (a wrapper around dracut --uefi) and signed with the MOK key. Because the cmdline is embedded and signed, it cannot be tampered with from the boot menu.

The ESP also holds:

  • EFI/BOOT/BOOTX64.EFI — shim (Microsoft-signed first-stage loader)
  • EFI/BOOT/grubx64.efi — systemd-boot (MOK-signed second-stage, loaded by shim)
  • EFI/BOOT/mmx64.efi — MokManager (for key enrollment at UEFI prompt)
  • EFI/BOOT/MOK.der — local MOK public certificate (for MokManager fallback)

Boot Entries

systemd-boot displays two entries:

shanios-blue  (Active)      ← currently running slot
shanios-green (Candidate)   ← standby / previous slot

The (Active) entry is set as the loader.conf default and given +3-0 boot count tries. The (Candidate) entry is the stable fallback.

Kernel Command Line

Key parameters embedded in each UKI:

root=/dev/mapper/shani_root          # LUKS device (or raw Btrfs partition if no encryption)
rootflags=subvol=@blue,ro,noatime,compress=zstd,space_cache=v2,autodefrag
ro                                   # read-only root
systemd.volatile=state               # /var is tmpfs; bind-mounts restore service state
lsm=landlock,lockdown,yama,integrity,apparmor,bpf
rd.luks.uuid=<uuid>                  # LUKS container UUID (encrypted systems only)
rd.luks.options=<uuid>=tpm2-device=auto   # TPM2 auto-unlock hint
rd.vconsole.keymap=us                # keyboard layout for LUKS passphrase prompt
resume=UUID=<uuid>                   # hibernation resume device (when swap configured)
resume_offset=<offset>               # Btrfs swapfile offset (when swap configured)
quiet splash                         # suppress kernel messages; show Plymouth

The cmdline is generated by gen-efi configure <slot> and written to /etc/kernel/install_cmdline_<slot> before being embedded in the UKI. This file is regenerated on every deploy and cannot be manually pre-edited — it is always overwritten.

The 99shanios Dracut Module

Shanios ships a custom dracut module at /usr/lib/dracut/modules.d/99shanios/ that adds three hooks to the initramfs:

| Hook | Phase | Priority | Purpose | |------|-------|----------|---------| | shanios-boot-failure-hook.sh | pre-mount | 90 | Writes /data/boot_hard_failure before root is mounted — persists if root mount fails | | shanios-overlay-etc.sh | pre-pivot | 50 | Mounts the /etc OverlayFS before pivot_root so systemd PID 1 sees user config from its first read | | shanios-boot-success-clear.sh | pre-pivot | 90 | Clears boot_hard_failure after root mounts successfully |

See Dracut Initramfs Module for full hook implementation details, mount options, and interaction with boot health services.

Boot Health & Automatic Rollback

Shanios uses systemd-boot's boot-counting mechanism plus its own two-tier failure detection:

Tier 1: Boot Counter (systemd-boot)

  1. +3-0 — set on the new slot's EFI entry at deploy time (3 tries remaining, 0 bad)
  2. On each failed boot, the firmware decrements the counter
  3. At 0, systemd-boot falls back to the previous entry — before the OS even starts

Tier 2: Application-level Health (systemd services)

| Service | When | What | |---------|------|------| | mark-boot-in-progress.service | local-fs.target | Writes /data/boot_in_progress, clears old markers | | mark-boot-success.service | multi-user.target | Writes /data/boot-ok, clears boot_in_progress, removes stale failure markers for the current slot | | bless-boot.service | After mark-boot-success.service | Calls bootctl set-good — stops the boot counter countdown | | check-boot-failure.timer | OnBootSec=15m | Fires once; if boot_in_progress exists and boot-ok is absent, writes /data/boot_failure |

On first login after a fallback, shani-update detects the mismatch between the booted slot and /data/current-slot, then offers rollback.

Boot Marker Files

| File | Location | Meaning | |------|----------|---------| | boot_in_progress | /data/ | Boot started but not yet confirmed successful | | boot-ok | /data/ | System reached multi-user.target successfully | | boot_failure | /data/ | Soft failure: system fell back after failing to reach multi-user.target | | boot_failure.acked | /data/ | User acknowledged the failure; rollback was offered | | boot_hard_failure | /data/ | Hard failure: root filesystem failed to mount (dracut hook) |

LUKS2 Unlock

If full-disk encryption is enabled, the initramfs unlocks the LUKS2 container before mounting the Btrfs partition:

  • Manual: Plymouth passphrase prompt (keyboard layout from rd.vconsole.keymap)
  • TPM2 auto-unlock: systemd-cryptenroll binds the key to PCR values; no passphrase required if the boot chain is unmodified
  • Recovery: Boot from USB → cryptsetup open /dev/sdXY shani_root → mount and repair

The initramfs includes /etc/crypttab (via dracut.conf.d/99-crypt-key.conf) so the LUKS device is known at early-boot time.

Checking Boot State

# Which slot am I running?
cat /data/current-slot

# systemd-boot status and boot entries
bootctl status
bootctl list

# Boot counter for current entry
bootctl status | grep -A3 "Current Boot"

# Boot marker state
ls -la /data/boot-ok /data/boot_in_progress /data/boot_failure /data/boot_hard_failure 2>/dev/null

# Recent boot logs
journalctl -b 0 --no-pager | head -60

# Previous boot (useful after a rollback)
journalctl -b -1 --no-pager | head -60

# Boot chain service status
systemctl status mark-boot-success.service bless-boot.service check-boot-failure.timer

# Comprehensive boot diagnostics
shani-health --boot