Architecture

The landing page introduces the split: the kernel owns the hardware, the orchestration layer decides what it does, and they meet at one checked boundary. This page is how that split is drawn — where the boundary sits, what crosses it, and the design decisions that fall out of it.

The FFI boundary is a feasibility decision

The boundary between the two layers is not merely a gate that bytecode passes through. It is where a request is checked against the real state of the machine.

This is the split found in aerospace and automotive control software: a high-level controller states what it wants; the layer beneath it decides feasibility against the real world and then executes it, saturates it, or rejects it.

In Lambda OS that decision is made in the FFI handler — not in the script, not in the VM, but in the C function the kernel registers. The bytecode is the intent; the FFI handler is where intent meets mechanism and the machine's real state is checked. A mission that asks for something the machine cannot, or must not, do does not get it — the flight controller's safety envelope is exactly this pattern, native and one layer down from the mission that proposes to it.

What is native, and what is bytecode

Not everything is a script. A loop that cannot miss a deadline is a native Zig task, written in a language with predictable, measurable worst-case cost.

The orchestration layer handles the parts that only need to be eventually right — decide the next waypoint, restart a crashed worker, report a status — where a few microseconds of jitter is harmless. The parts that must never miss a deadline are native, and a preempting timer means a runaway script cannot stop one.

The rule for where a thing goes: if a late answer is a failure, it is native; if a late answer is merely late, it can be bytecode.

BMP — one core per actor

The concurrency model is bound multiprocessing: every VM task is pinned to one core and never migrates.

This is both a necessity and a payoff. The VM's process-wide run-state is a single per-core set, so a task that moved between cores would need cross-core locking around it; pinning removes that. And it is exactly what the actor model already wants — actors share no mutable state and communicate only by messages, so the VM's globals need one set per core, not a lock.

The result is a multi-core system with almost no locks: the interrupt-disabled sections are all a few instructions long, around genuinely shared data — the mailbox, the console, the transmit ring.

One trust domain

All bytecode comes from the same operator over a trusted channel. There is no instruction-level verifier for hostile bytecode, by design.

The confinement is there for a different reason: to contain a bug, not to defend against an adversary. Each VM task runs at the lowest privilege the architecture offers and reaches the kernel through a single syscall gate, and that confinement is drawn per actor — an address space each where there is an MMU, a PMP or MPU region each where there is not. So a fault stays inside the actor that caused it.

Isolation here is a robustness boundary, not a multi-tenancy boundary. The target is a dedicated appliance running the operator's own software, where the threat is a bug, not an adversary. How far the confinement holds on each target is on the Isolation page.

The layer model

Lambda C bytecode  → intent, hardware-isolated   (ring 3 / EL0 / U-mode / unprivileged)
      │  syscall gate (int 0x80 / svc / ecall) + FFI (C ABI)
Arch-neutral kernel → scheduler · network · VM host   (one source, five targets)
      │  HAL selector  (resolved at compile time)
arch layer         → cpu · console · mmu · intc · trap · gdt · nic

Three responsibilities, cleanly separated: bytecode says what to do, FFI handlers validate it against current state, and the kernel and its drivers own the hardware. Each architecture reaches a common kernel entry point through its own boot path — a UEFI bootloader on x86, OpenSBI on riscv64, EL1 on aarch64, bare-metal firmware on the MCUs — and then runs identical arch-neutral code. The cross-architecture layer itself is on the Portability page.

Position in the Lambda series

Lambda OS is a from-scratch RTOS that stands on its own — the kernel and its native tasks depend on no script, and a deployment can be entirely native.

Its distinctive upper layer is an orchestration layer of hardware-isolated actors, written in Lambda C bytecode. Lambda C is the embedded orchestration VM of the Lambda series, normally embedded into a small C program that owns the hardware, registers the FFI surface, and decides which bytecode to run.

Lambda OS is what that program looks like when it grows into a preemptive, multi-core, networked operating system: each Lambda C VM becomes a hardware-isolated actor within it. The kernel does not depend on it; the two are siblings that fit together by design.