Skip to content

03 — Real-Time Operating System

Status · reconciled 2026-08-30. The product audio contract is cpal -> ALSA, with one Auvra process owning the device. JACK is not required by the MVP.

The OS turns the N100 into a deterministic audio appliance. Three concerns: a real-time kernel, the audio stack, and RT tuning for the 4-core N100. (Silent boot is covered in 07.)

1. Real-time kernel: PREEMPT_RT is mainline

Section titled “1. Real-time kernel: PREEMPT_RT is mainline”

Since Linux 6.12 (Nov 2024, an LTS kernel) the full PREEMPT_RT preemption model is merged into the mainline kernel — no out-of-tree patch needed.12 x86_64 is fully supported, so the N100 is covered. A fully-preemptible RT kernel is selected with:

# Kernel config (General Setup → Preemption Model → "Fully Preemptible Kernel (Real-Time)")
CONFIG_PREEMPT_RT=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_NO_HZ_FULL=y # tickless isolated CPUs
CONFIG_RCU_NOCB_CPU=y # offload RCU callbacks from RT cores

Distro availability in 2026:34

Distro RT kernel How
Debian 13 “Trixie” mainline 6.12-rt apt install linux-image-rt-amd64 — easiest free path
Ubuntu 24.04 LTS 6.8 + RT via Ubuntu Pro (free ≤ 5 machines); free for all from 26.04
Fedora / Fedora Jam 6.12+ kernel-rt vanilla repos / Jam spin
Arch linux-rt-lts AUR
flowchart LR
    subgraph PROTO["Prototype (develop & tune)"]
      D["Debian 13 Trixie<br/>+ linux-image-rt-amd64<br/>+ development tools"]
    end
    subgraph PROD["Shippable product"]
      Y["Yocto image<br/>meta-realtime + read-only rootfs<br/>+ RAUC A/B OTA"]
    end
    D -->|"port app, freeze deps"| Y
  • Prototype → Debian 13 Trixie with the packaged RT kernel. Full debugging tools, apt convenience, and the distribution ALSA stack make it fast to stand up.3
  • Product → Yocto minimal image: SquashFS read-only rootfs + tmpfs overlay, writable data partition for patches/settings, RAUC A/B updates. Result: < 200 MB image, 3–5 s boot, reproducible, power-loss-safe, nothing of the OS visible to the user.56 Buildroot is a lighter alternative if OTA isn’t required.

Rationale: a desktop audio distro is perfect for development but wrong for an appliance — mutable rootfs (corruption risk on power-cut), slow boot, and exposed internals. The immutable Yocto image fixes all three.

flowchart TB
    APP["Auvra app<br/>cpal callback + engine"]
    ALSA["ALSA<br/>(bench: snd-usb-audio<br/>integrated: auvra-pcie)"]
    HW["Audio interface"]
    APP -->|"exclusive PCM stream<br/>64–128 frames"| ALSA --> HW

For a dedicated single-app synth, Auvra uses bare ALSA through cpal:

  • ALSA is the stable Linux device ABI for both class-compliant USB bench hardware and the selected FPGA integration target. The Auvra process owns one PCM stream exclusively; no routing server sits in the audio path.
  • cpal supplies the Rust callback abstraction used by the same engine on CoreAudio during Mac development. Its Linux backend opens ALSA directly.
  • JACK/PipeWire remain optional future platform adapters for desktop routing, recording workflows or development. They are not product dependencies.

The buffer contribution is deterministic; actual round-trip latency also includes converter and driver safety buffers and must therefore be measured on each target interface:

ALSA period @ 48 kHz One period Two-period software budget
64 frames 1.33 ms 2.67 ms
128 frames 2.67 ms 5.33 ms
256 frames 5.33 ms 10.67 ms

4. RT tuning checklist (Intel N100, 4 cores)

Section titled “4. RT tuning checklist (Intel N100, 4 cores)”

4-core caveat: isolate 2–3 cores for audio and leave core 0 for the kernel, IRQs, housekeeping and UI. Do not isolate all four — RCU/watchdog/kernel threads will starve.7

isolcpus=1,2,3 nohz_full=1,2,3 rcu_nocbs=1,2,3 \
threadirqs irqaffinity=0 \
intel_idle.max_cstate=1 processor.max_cstate=1 \
intel_pstate=disable skew_tick=1 tsc=nowatchdog nosoftlockup rcu_nocb_poll
Flag Effect
isolcpus=1,2,3 Remove cores 1–3 from the scheduler; pin the synth with taskset/chrt.
nohz_full=1,2,3 Stop the scheduling tick on isolated cores → no periodic timer jitter.
rcu_nocbs=1,2,3 Offload RCU callbacks to core 0.
threadirqs / irqaffinity=0 Threaded IRQs, all pinned to core 0 (off the audio cores).
intel_idle.max_cstate=1 / processor.max_cstate=1 Cap C-states → avoid deep-sleep exit latency (100–300 µs).
intel_pstate=disable Lets the performance cpufreq governor lock clocks.
tsc=nowatchdog nosoftlockup skew_tick=1 Remove watchdog/lock-detector preemption bursts.
Terminal window
# performance governor
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# allow unthrottled RT on isolated cores
echo -1 > /proc/sys/kernel/sched_rt_runtime_us
@audio - rtprio 95
@audio - memlock unlimited
@audio - nice -19

Add the synth user to the audio group; ensure pam_limits.so is active. The engine should mlockall() to avoid page-fault stalls.

Use the rtirq script to raise the sound-card IRQ thread priority (e.g. snd at 85) after boot — complementary to threadirqs.

Terminal window
# scheduling jitter under load (target Max < ~30 µs with isolation)
taskset -c 1 cyclictest -m -p90 -i500 -D 30m -h400 -q
# detect SMI/firmware-induced stalls the kernel can't see
hwlatdetect --duration=60
# config audit
pip install rtcqs && rtcqs

N100 field note: at least one report found that disabling BIOS C-states increased latency on N100 hardware — its firmware manages idle well, and the kernel *.max_cstate=1 flags suffice. Measure both ways with cyclictest before committing BIOS changes.7

SMIs are invisible to the kernel and can add 50–300 µs. Reduce them in BIOS: disable unused VT-x/VT-d, USB legacy support, and aggressive power features; lock the CPU frequency. There is no kernel fix — detect with hwlatdetect.8

  • cyclictest Max jitter < 30 µs under load (video/USB/network stress).
  • The cpal -> ALSA stream is stable at 64–128 frames with no xruns over an hour of playing.
  • hwlatdetect shows no SMI spikes > 50 µs.
  1. Phoronix, “Real-Time PREEMPT_RT Support Merged For Linux 6.12.” https://www.phoronix.com/news/Linux-6.12-Does-Real-Time ↩

  2. Linux Foundation RT wiki, “PREEMPT_RT versions.” https://wiki.linuxfoundation.org/realtime/preempt_rt_versions ↩

  3. Debian, linux-image-rt-amd64 (Trixie). https://packages.debian.org/trixie/linux-image-rt-amd64 ↩ ↩2

  4. Canonical, “Real-time Ubuntu 24.04 LTS.” https://ubuntu.com/blog/real-time-24-04 ↩

  5. Incredibuild, “Yocto vs Buildroot.” https://www.incredibuild.com/blog/yocto-or-buildroot-which-to-use-when-building-your-custom-embedded-systems ↩

  6. meta-readonly-rootfs-overlay (SquashFS + OverlayFS for Yocto). https://github.com/marcusfolkesson/meta-readonly-rootfs-overlay ↩

  7. LinuxCNC forum, “Intel N100” latency thread (isolcpus, C-state finding). https://forum.linuxcnc.org/18-computer/50817-intel-n100 ↩ ↩2

  8. Linux Foundation, “SMI latency” debugging guide. https://wiki.linuxfoundation.org/realtime/documentation/howto/debugging/smi-latency/start ↩