Skip to content

SpaceOS on the spacecraft

SpaceOS runs on the payload side of the spacecraft. It does not fly the vehicle. The flight computer remains in charge and continues running if the payload computer fails.

Flight OS, container platform, and SpaceOS

SpaceOS handles payload middleware. A flight OS and a general-purpose container platform each solve a different problem, and this table sets the three side by side.

Flight OSContainer platformSpaceOS
ExamplesVxWorks, RTEMS, PikeOSDocker or K3s on Linux, Yocto plus containersMirageOS and Unikraft unikernels on Solo5 over KVM
JobThe bus: attitude and orbit control, power, thermal, instrument timingGeneral-purpose application deployment on LinuxPayload middleware: deploying, isolating, and supervising mission applications
Real-timeHard real-time schedulingNoneNone
IsolationARINC 653 partitioning, separation kernelLinux namespaces, shared kernelOne VM per workload, no shared kernel; a container mode shares the control-plane kernel
FootprintMinimal, bare-metal or RTOS imageHundreds of MBSingle-digit MB per unikernel
UpdatesFull image replacement, infrequentRegistry pullSigned OCI content over CCSDS links, health-gated with automatic fallback
Written byEmbedded specialists in C or AdaApplication developers using container toolingApplication developers in OCaml, C, C++, Python, or Rust

SpaceOS keeps the Docker workflow: build an image, push it to a registry, deploy it to a target. Each deployed unit is a unikernel with no kernel underneath it. VxWorks or PikeOS runs the bus, and SpaceOS runs on the payload computer, handling the software lifecycle for work that has no control-loop deadline.

Software domains

A spacecraft running SpaceOS has two software domains:

  • The flight domain controls attitude, propulsion, power, and spacecraft commands. It usually runs a real-time operating system (RTOS) with a flight-software framework such as JPL’s F-Prime or NASA’s cFS. It has its own boot and its own fault detection, isolation, and recovery (FDIR). It also has a hardware watchdog, a timer that resets the computer if software stops refreshing it.
  • The payload domain runs SpaceOS on a payload or mission computer. SpaceOS checks and starts isolated workloads. It also handles payload data sent to and from ground.

The flight computer boots and recovers without SpaceOS. SpaceOS may read telemetry and relay a signed command, but it cannot restart the flight computer or refresh its watchdog.

The flight computer and the SpaceOS payload computer exchange authorized frames over the spacecraft bus. The payload computer connects separately to instruments and the ground link.

The flight computer runs the RTOS, flight framework, control functions, FDIR, and watchdog. The payload computer runs the SpaceOS control plane and isolated workloads, each in a hardware-isolated micro-VM (hvt) or a Linux container (runc). A spacecraft bus carries frames between the two domains. Each frame is tagged with an APID, the CCSDS number that says which stream it belongs to. The payload computer connects separately to the ground link and to any bulk-data instrument links.

The domains may run on separate computers. They may also share hardware under a separation kernel or a flight-owned hypervisor. The flight computer keeps the same control in every layout.

Inspect the spacecraft boundary

Start with the target record. Connecting the node stores its profile, orbit, ground route, and signing custody; space target show reads that record back:

Terminal window
$ space target connect sat-42 --profile cm5-dev \
> --endpoint ipn:7.1 --cla-address sat-42.example:4556 \
> --tle sat-42.tle --station 37.619,-122.375,0.004
Generated signing key: /tmp/space-docs/config/keys/target-sat-42-boot.pem
Generated acknowledgement key: /tmp/space-docs/config/keys/target-sat-42-ack.pem
target/sat-42 connected
$ space target show sat-42
name : sat-42
context : local
profile : cm5-dev@sha256:4d9ea311b399dc777b09e846f1c637dbf04e49d579a79cc42a7a2cfa00181828
board : raspberrypi-cm5
signing-key : /tmp/space-docs/config/keys/target-sat-42-boot.pem
dtb : (firmware stock)
kernel : (composition default)
state-key : (none: unauthenticated boot-state)
ack-key : /tmp/space-docs/config/keys/target-sat-42-ack.pem
recipient-key: (none: whole-bundle delivery only)
recipient-id : (none)
endpoint : ipn:7.1
cla-address : sat-42.example:4556
contact : derived from sat-42.tle over 37.619,-122.375,0.004
rate : 1e+06 B/s (default)

Resolve the release without sending it:

Terminal window
space deploy payload:release --target sat-42 --plan

Check which telemetry IDs the payload may use and where its messages may go. The plan also shows what resets the payload computer and which key approves its boot image. Then deploy and watch the result:

Terminal window
space deploy payload:release --target sat-42
space status <deploy-id>

space status reports when the files arrive, when the node installs them, and when the new software passes its health checks. File delivery alone does not mean that the software is running.

  • The spacecraft bus carries fixed-size, APID-tagged frames in both directions: flight telemetry, events, and parameters flowing to payload and ground; authorized commands flowing back. An isolated bus adapter owns the physical device. It enforces direction and frame bounds, and it fails closed on malformed traffic. Applications reach the bus through the adapter.
  • The flight computer checks every command. Each command names its target and action. It also carries limits, a sequence number, an expiration, and a signature. SpaceOS relays the command. The flight computer checks it before acting and reports the result in telemetry.
  • The radio belongs to whichever domain the integration gives it. With a SpaceOS system image, SpaceOS frames the downlink itself, running CFDP over BPv7/BPSec end to end and SDLS per hop. In a daemon install it can hand the framed stream to your flight software for transmission.
  • High-throughput instrument data uses its own bulk link, granted separately from the command path. That link runs over a spacecraft-grade serial fabric such as SpaceWire or SpaceFibre.

FDIR ownership

SpaceOS handles each failure at the smallest boundary that contains it, and its responses never reach into the flight domain. An SEU is a single-event upset, a bit flipped by ionizing radiation.

FailureDetected byResponseContained to
Service crashes or fails its healthcheckThe runner’s probeIsolate, back off, relaunch that serviceOne service
Guest wedges (alive but silent)Heartbeat stall on the supervision pageRestart that partitionOne partition
SEU corrupts stored payload dataVerified reads (dm-verity) on the read-only root; record CRCsRead fails; the affected partition restartsOne partition
SEU corrupts payload memory in useYour platform’s memory error reporting, where the payload computer has itWhatever that reporting drives; SpaceOS adds no detection of its ownNot bounded by SpaceOS
Payload control plane faultsspace-init’s internal FDIRPayload safe mode: the payload stops, the node stays up and reachableThe payload computer
Payload computer hangsHardware watchdog on the payload nodeReset; boot falls back to the last healthy releaseThe payload computer
Flight domain faultsYour FDIR and your watchdogYour recovery, untouched by any of the aboveYour domain

Read the two SEU rows as a boundary. dm-verity hashes blocks read from the read-only root, and record CRCs cover stored data, so an upset that corrupts either is caught on the next read. Neither sees a bit flip in a running process’s heap, in a page table, or in a register. Detecting those needs memory error reporting from the payload computer, so the mission owns that choice: an ECC part reports and corrects, and a part without ECC cannot tell you an upset happened. Pick the hardware for the orbit and the mission life you are flying.

Payload-domain failures stay in the payload domain. A dead payload computer cannot reset flight, refresh its watchdog, suppress its FDIR, or claim a more privileged command channel. When the bus is congested, the adapter may drop payload telemetry. Payload traffic never blocks a control loop.

Payload safe mode

Safe mode is the response to a fault in the payload control plane. The payload stops. The node stays powered and reachable.

ComponentIn safe mode
Payload workloadsStopped
Network switch and uplinkRunning
Deploy receiverRunning
RunnerRunning
Log and metric collectorsRunning

The node does not power off. A powered-off payload computer answers no uplink, so the fault that triggered safe mode would stay uncorrected until the next opportunity to power-cycle the hardware. Keeping the link and the deploy receiver running means you can uplink a recovery release to a node that is already in safe mode, and the collectors are how you see the node entered it.

To leave safe mode, apply a release or reboot the node. There is no separate exit command. FDIR takes a new baseline against the state the node reaches afterwards.

One condition does power the node off, and it is not safe mode: a one-shot node powers off after every workload runs to completion.

A critical dom0 daemon that crash-loops past its restart bound does not power the node off either. The node stays up degraded, with the uplink and the deploy receiver still running, because a powered-off node is a node no recovery release can reach. Rolling back is the operator’s decision, taken over a link that is still there.

The payload watchdog

space-init arms the watchdog on a board that exposes one, once the node reaches its serving state. A development VM with no watchdog device reports that at boot and runs unwatched.

The refresh is conditional on the runner replying. space-init refreshes the device only when the runner answers a request on its control socket. A watchdog refreshed on a timer alone catches a stopped kernel and misses a wedged control plane, because the timer keeps firing after the runner stops answering. Tying the refresh to a reply the runner has to produce covers that case.

When the runner stops answering, space-init stops refreshing and the hardware resets the node. space-init does not reset the node itself: a wedged control plane cannot be relied on to run a shutdown path. After the reset, the boot decision finds the trial unconfirmed and falls back to the last healthy release.

The default is a refresh every 15 seconds against a 60 second timeout, which tolerates three consecutive missed refreshes. Set the device timeout on the kernel command line for your board. space-init reads the effective timeout back from the driver and refreshes against that value. A shorter device timeout tightens the refresh interval so at least two attempts still fit inside it.

Know what SpaceOS can control

  • It makes no hard-real-time guarantee and schedules no fixed time windows; anything with a control-loop deadline stays in your domain.
  • It cannot originate flight commands. It relays signed objects that your domain verifies for itself.
  • Its workloads run inside fixed resource envelopes set at deployment: memory per partition and CPUs per service. A runaway payload job starves inside its own envelope and leaves the bus alone.
  • Workload and system updates apply only to the payload computer. They are health-gated with automatic fallback, and they survive a power loss at any point.

Integration inputs

Integration needs four inputs:

  1. The bus binding. Select the physical transport (MIL-STD-1553, CAN, serial, SpaceWire) and the frame budget; the payload-side protocol is the same fixed-size message format in every topology.
  2. The APID plan. Declare which telemetry your domain publishes and which command streams it accepts; SpaceOS routes by identity underneath and treats APIDs as labels.
  3. The command authority. Pin the public keys whose signed commands your domain will accept. Key custody stays with you, under the same contact-window constraints that shape the platform’s own key handling.
  4. The simulator, if you want one. A flight simulator attaches as a bus peer at deploy time. It speaks the same interfaces as the real flight node, and the release provenance records that a simulator stood in for it. Tests run against the simulator therefore exercise the interfaces flight will use.

Fault-injection tests qualify a physical bus binding. They cover malformed traffic, a saturated payload, an adapter crash, cable loss, and stale or duplicated commands, all while your watchdog and FDIR keep running.