GUIDE · PREVIEW
GUIDE / CON.21
source: docs/guide/concepts/Kernel Configuration.md
Concepts

Kernel Configuration

The Problem

FortrOS builds multiple kernel images for different stages of the boot chain. Each has different requirements: the bootstrapper needs to run on unknown hardware, the preboot needs to be small and fast, and the node kernel needs virtualization and storage features. Getting kernel config wrong is silent -- the kernel compiles fine but fails on hardware it doesn't have drivers for, or includes drivers that waste memory and boot time.

Three Kernels, Three Strategies

Bootstrapper Kernel: Maximum Compatibility

The bootstrapper runs once on unknown hardware. It PXE boots, downloads the preboot, writes it to disk, and reboots. It never runs again. The priority is: boot on everything, ask questions never.

Start from a distro's "generic" or "server" config (Alpine LTS, Debian, Fedora) and strip what's clearly unnecessary (sound, graphics acceleration, exotic filesystems). Keep everything else. The cost of extra drivers is a larger kernel (~15MB vs ~8MB) and slightly slower boot (~1s). The cost of a missing driver is a bricked provisioning session.

Must have:

  • All common NIC drivers: Intel (e1000, e1000e, igb, igc), Realtek (r8169), Broadcom (tg3, bnx2), USB ethernet (asix, cdc_ether, r8152)
  • All common storage: AHCI, NVMe, USB mass storage, virtio-blk (for VPS provisioning)
  • Display: EFI framebuffer (efifb), VESA framebuffer (vesafb), simpledrm, framebuffer console. The admin needs to see what's happening.
  • USB: XHCI, EHCI, OHCI (for USB keyboards, YubiKeys, USB ethernet)
  • WiFi: iwlwifi, ath9k, ath10k (for laptop provisioning)
  • Basics: kexec, DHCP (via busybox), EFI stub, ACPI, PCI, PCIe

Nice to have:

  • Netconsole (remote printk over UDP for debugging)
  • EFI earlycon (display output before framebuffer initializes)

Don't need:

  • KVM/virtualization (bootstrapper doesn't host VMs)
  • dm-crypt/LUKS (bootstrapper doesn't encrypt anything)
  • WireGuard (bootstrapper uses TLS, not overlay network)
  • CRDTs, gossip (bootstrapper is not an org member)
  • Confidential computing (SEV-SNP, TDX)

Preboot Kernel: Lean and Secure

The preboot runs on known hardware classes (the org knows what nodes it has). It boots from the ESP, authenticates to the org, unlocks /persist, and kexecs into the node kernel. It runs for seconds, not hours.

Start from a minimal config and add what's needed. The preboot kernel should be as small as possible to:

  • Fit in the UKI on the ESP (with initramfs)
  • Boot fast (every second in preboot is a second the node isn't working)
  • Minimize attack surface (preboot holds sensitive keys in memory)

Must have:

  • NIC drivers for org's hardware: only what's deployed, not everything. A homelab with all Intel NICs only needs e1000e. A mixed fleet adds r8169.
  • WiFi: the preboot needs network to reach the org for auth. A laptop on WiFi-only needs iwlwifi/ath* in the preboot. WiFi credentials come from UEFI vars (saved by main OS on previous boot) or a captive portal flow. Without WiFi, a laptop can't authenticate on cold boot away from the org's LAN.
  • Storage: whatever the org uses (NVMe, AHCI, virtio for VPS)
  • LUKS/dm-crypt: unlock /persist
  • TPM 2.0: read/write preboot_secret and signing key
  • kexec: hand off to node kernel
  • KHO (6.19+): preserve memory across kexec
  • EFI stub: boot from ESP
  • PCI MSI: required for cloud-hypervisor VMs
  • USB: XHCI, EHCI (YubiKey for hibernate resume, USB ethernet fallback)

Don't need:

  • Sound, GPU acceleration, Bluetooth
  • KVM, VFIO (preboot doesn't host VMs)

Node Kernel: Full Featured

The node kernel runs the actual workloads. It needs everything the node's role requires. This is the kernel that stays running for days/weeks.

Start from the preboot config and add:

  • KVM: VM hosting (cloud-hypervisor uses KVM)
  • VFIO/IOMMU: device passthrough (GPU, NVMe to VMs)
  • WireGuard: overlay network
  • dm-thin: shard + scratch storage pools
  • cgroup v2: container isolation
  • Namespaces: container isolation
  • SEV-SNP/TDX: confidential computing (if hardware supports it)
  • Netfilter: iptables/nftables for VM networking

The node kernel can also be optimized for the specific CPU architecture via localmodconfig after the first boot (Phase 2-3 in the roadmap).

Derivation Strategy

Bootstrapper: Start from a Distro Config

Don't hand-roll. Take a known-working distro config that boots on the widest range of hardware:

# Get Alpine's LTS config (known to boot on most x86_64 hardware)
wget alpine-lts-config
# Or Debian's generic config
# Or Fedora's server config

# Strip what bootstrapper doesn't need
scripts/config --disable SOUND
scripts/config --disable DRM_I915    # GPU acceleration
scripts/config --disable DRM_AMDGPU
scripts/config --disable XFS         # exotic filesystems
scripts/config --disable BTRFS
scripts/config --disable NFS_FS

# Ensure what it DOES need
scripts/config --enable KEXEC
scripts/config --enable EFI_STUB
scripts/config --enable FB_EFI
scripts/config --enable FRAMEBUFFER_CONSOLE
scripts/config --enable E1000E
scripts/config --enable R8169
scripts/config --enable VIRTIO_NET
scripts/config --enable VIRTIO_BLK

# Resolve dependencies
make olddefconfig

The result is a large (~15MB) but universally compatible kernel. This is correct for a one-time bootstrapper.

Preboot and Node: Build Up from Minimal

Start from tinyconfig or defconfig and add only what's needed:

make tinyconfig
# Add architecture basics
scripts/config --enable 64BIT
scripts/config --enable SMP
scripts/config --enable EFI
scripts/config --enable EFI_STUB
scripts/config --enable ACPI
scripts/config --enable PCI
scripts/config --enable PCI_MSI
# Add specific drivers for org's hardware
scripts/config --enable E1000E        # if org uses Intel NICs
scripts/config --enable NVME          # if org uses NVMe
# ... etc
make olddefconfig

Hardware Probe Informs Config

The bootstrapper runs a hardware probe on first boot. The probe output tells the org what drivers the preboot and node kernels need for this specific machine. Future preboot/node images can be built with only the necessary drivers, reducing size and attack surface.

Bootstrapper boots on unknown Dell Optiplex
  -> probes: Intel I219-LM NIC, NVMe SSD, SATA HDD, Intel UHD 630 GPU
  -> reports to org: needs e1000e, nvme, ahci, i915 (for GPU passthrough)
  -> org builds preboot with: e1000e, nvme, ahci (lean)
  -> org builds node with: e1000e, nvme, ahci, i915, kvm, vfio (full)

Kconfig Silent Drops

Kconfig silently drops options whose dependencies aren't met. This is the most common source of "kernel compiles fine but doesn't work" bugs. For example, CONFIG_PCI_MSI=y requires CONFIG_PCI=y. If PCI isn't enabled, MSI is silently removed during make olddefconfig.

The build system should verify after every kernel build that no explicitly set option was dropped. See verify_kconfig() in buildroot/build.sh.

Links