Skip to content

Releases: xinix00/HopOS

HopOS v1.5.5

Choose a tag to compare

@xinix00 xinix00 released this 27 Jul 16:11

Every flavor now boots with something. Both the GUI and the headless assets ship a working default hopos.cfgone edit required (hopos.apikey), then boot:

  • GUI: a ready-made desktop — display, launcher and the app catalog straight from the hop-os-surf rolling release, no addresses to fill in.
  • Headless: a bare node waiting for work over the HOP API, with commented hopos.init[] lines in the template to seed your own baseline.

Editing that file on the FAT partition is node management: no shell, no rebuild. The Pi 4 gains the same initramfs hopos.cfg boot recipe as the Pi 5 (full JSON job specs, no bootargs size limit).


Prebuilt, signed boot images — https://gethop.org/hopos/ for the 5-minute quickstart.

  • BOOTAA64.EFI + hopos.cfg — any UEFI arm64 box: EFI to EFI/BOOT/, config in the stick root
  • hopos-rpi5.zip / hopos-rpi4.zip — unzip onto the SD bootfs (config included)
  • *-headless — the same images with zero GUI code linked; hopos-headless.cfg is their config template. For UEFI, rename BOOTAA64-headless.EFI to BOOTAA64.EFI on the stick.

Verify: ssh-keygen -Y verify -f allowed_signers -I hello@gethop.org -n gethop-release -s SHA256SUMS.sig < SHA256SUMS && shasum -a 256 -c SHA256SUMS

HopOS v1.5.4 — hairpin

Choose a tag to compare

@xinix00 xinix00 released this 27 Jul 13:12

Hairpin NAT. Publish ports outward, let DNS pick the host — and when that host happens to be your own node, the switch takes the shortcut. A slot dialing the node IP on a published port is redirected internally: DNAT + masquerade in a single pass over the two existing tables (no new state), delivered ring-to-ring — not a byte leaves the NIC. Reply recognition is unambiguous: only a neighbour slot can carry the node IP as a destination (masquerade replies arrive via the uplink). Covered both ways by hairpin_test.

This retires the last-but-one deliberate KISS gap from day one; the remaining one (node IP from inside for unpublished ports) stays — node services live on 10.100.0.1.


Prebuilt, signed boot images — https://gethop.org/hopos/ for the 5-minute quickstart.

  • BOOTAA64.EFI — any UEFI arm64 box: copy to EFI/BOOT/ on a FAT USB stick, add hopos.cfg
  • hopos-rpi5.zip — Raspberry Pi 5: unzip onto the SD bootfs
  • hopos-rpi4.zip — Raspberry Pi 4: unzip onto the SD bootfs
  • *-headless — the same images built with GUI=0: not a disabled GUI but zero GUI code linked. For UEFI, rename BOOTAA64-headless.EFI to BOOTAA64.EFI on the stick.

Verify: ssh-keygen -Y verify -f allowed_signers -I hello@gethop.org -n gethop-release -s SHA256SUMS.sig < SHA256SUMS && shasum -a 256 -c SHA256SUMS

HopOS v1.5.3

Choose a tag to compare

@xinix00 xinix00 released this 27 Jul 08:25

apphttp bugfix. Serve's accept loop could spin when the app netstack returned a temporary error or an empty accept (nil, nil) — eating the entire core: the SURF display sat at 100% CPU, never answering, without a single log line. net/http has a safety net here (growing back-off on temporary errors); apphttp lacked it, and that difference was exactly the difference between a working and a dead display.

Fixed: exponential back-off (1ms→100ms) on temporary errors, and an empty accept without an error now ends the loop with a reason — fail loudly, so the app logs it and the node restarts it. Pinned by a regression test (TestServeNeverSpins).


Prebuilt, signed boot images — https://gethop.org/hopos/ for the 5-minute quickstart.

  • BOOTAA64.EFI — any UEFI arm64 box: copy to EFI/BOOT/ on a FAT USB stick, add hopos.cfg
  • hopos-rpi5.zip — Raspberry Pi 5: unzip onto the SD bootfs
  • hopos-rpi4.zip — Raspberry Pi 4: unzip onto the SD bootfs
  • *-headless — the same images built with GUI=0: not a disabled GUI but zero GUI code linked. For UEFI, rename BOOTAA64-headless.EFI to BOOTAA64.EFI on the stick.

Verify: ssh-keygen -Y verify -f allowed_signers -I hello@gethop.org -n gethop-release -s SHA256SUMS.sig < SHA256SUMS && shasum -a 256 -c SHA256SUMS

HopOS v1.5.2

Choose a tag to compare

@xinix00 xinix00 released this 27 Jul 06:03

Built against HOP v0.20.1.

No capacity is pending, not a crash. A placement failure (no free core, pool doesn't fit) is now marked hopos.ErrNoCapacity, so HOP parks the job as unplaceable instead of restart-looping it — every retry used to re-download the image just to fail again.

The two-sharegroup desktop recipe ships in hopos.cfg.example and docs/config.md: desktop packs the display + launcher chrome on one core; apps stacks every window app on the remaining cores (cpu_shares sizes the pool, not a per-app quota) — so the eighth window is just another cage on the pool, not a rejection. The catalog pulls straight from the hop-os-surf rolling release.


Prebuilt, signed boot images — https://gethop.org/hopos/ for the 5-minute quickstart.

  • BOOTAA64.EFI — any UEFI arm64 box: copy to EFI/BOOT/ on a FAT USB stick, add hopos.cfg
  • hopos-rpi5.zip — Raspberry Pi 5: unzip onto the SD bootfs
  • hopos-rpi4.zip — Raspberry Pi 4: unzip onto the SD bootfs
  • *-headless — the same images built with GUI=0: not a disabled GUI but zero GUI code linked. For UEFI, rename BOOTAA64-headless.EFI to BOOTAA64.EFI on the stick.

Verify: ssh-keygen -Y verify -f allowed_signers -I hello@gethop.org -n gethop-release -s SHA256SUMS.sig < SHA256SUMS && shasum -a 256 -c SHA256SUMS

HopOS v1.5.1

Choose a tag to compare

@xinix00 xinix00 released this 26 Jul 17:14

apphttp, both ways. The plain-HTTP client gained Do (method, body, chunked decoding) and a small Serve joins it — apps that serve a page (like the SURF display) no longer link net/http. Measured on the SURF apps: display 8.68 → 5.88 MB, launcher 8.42 → 5.48 MB, taskman 8.45 → 5.54 MB — zero crypto/tls symbols in the binary. The browser keeps net/http: it talks https to the outside world.

Desktop config from the rolling release. hopos.cfg example config now pulls the display/launcher artifacts straight from the hop-os-surf rolling release — same URL on every node, no file server of your own — and packs both onto one core via the desktop sharegroup, leaving every other core free for real apps.


Prebuilt, signed boot images — https://gethop.org/hopos/ for the 5-minute quickstart.

  • BOOTAA64.EFI — any UEFI arm64 box: copy to EFI/BOOT/ on a FAT USB stick, add hopos.cfg
  • hopos-rpi5.zip — Raspberry Pi 5: unzip onto the SD bootfs
  • hopos-rpi4.zip — Raspberry Pi 4: unzip onto the SD bootfs
  • *-headless — the same images built with GUI=0: not a disabled GUI but zero GUI code linked. For UEFI, rename BOOTAA64-headless.EFI to BOOTAA64.EFI on the stick.

Verify: ssh-keygen -Y verify -f allowed_signers -I hello@gethop.org -n gethop-release -s SHA256SUMS.sig < SHA256SUMS && shasum -a 256 -c SHA256SUMS

HopOS v1.5.0 — the review release

Choose a tag to compare

@xinix00 xinix00 released this 26 Jul 16:41

A full review pass, applied — net −800 lines at the same feature set:

  • One netstack. The lneto appnet variant is gone (dependency removed); gVisor's netstack is the stack.
  • Dead-peer detection moved to where it belongs. The switch no longer forges TCP RSTs on behalf of dead apps — silence can always be the network, and two layers already cover it (the task health check and the app's own ping). See docs/technical/networking.md.
  • apphttp: a minimal plain-HTTP/1.1 client for apps, as a separate package — net/http unconditionally links crypto/tls, measured on app/hello: applib alone 1.71 MB, + netstack 4.70 MB, + net/http 7.99 MB. Only who imports it pays.
  • Leaner GUI node side: the node keeps only the DeviceGrant (gui/fbgrant); the display-controller and compositor stack live app-side in the companion hop-os-surf repo. Every image builds bare or gui (GUI=0) — a bare node never gives away the glass.
  • hopos.cfg.example: a secrets-free sample next to the gitignored real config, so a fresh clone sees exactly what a node needs.

Prebuilt, signed boot images — https://gethop.org/hopos/ for the 5-minute quickstart.

  • BOOTAA64.EFI — any UEFI arm64 box: copy to EFI/BOOT/ on a FAT USB stick, add hopos.cfg
  • hopos-rpi5.zip — Raspberry Pi 5: unzip onto the SD bootfs
  • hopos-rpi4.zip — Raspberry Pi 4: unzip onto the SD bootfs
  • *-headless — the same images built with GUI=0: not a disabled GUI but zero GUI code linked. For UEFI, rename BOOTAA64-headless.EFI to BOOTAA64.EFI on the stick.

Verify: ssh-keygen -Y verify -f allowed_signers -I hello@gethop.org -n gethop-release -s SHA256SUMS.sig < SHA256SUMS && shasum -a 256 -c SHA256SUMS

HopOS v1.4.0 — SURF

Choose a tag to compare

@xinix00 xinix00 released this 20 Jul 18:45

SURF — a GUI on cores, not processes. A real desktop on HopOS: a display app owns the screen through the display controller (planes — still no GPU driver), and apps draw over SURF, a network protocol — so a window can come from any core on any node in the cluster. The kernel only gained a seam: DeviceGrants lend a plane window into an app's cage for the duration of its lifecycle; built without the gui flavor, no grant exists. The boot medium can now carry a full desktop: hopos.init[] starts the display + launcher, hopos.apps[] is the launcher's catalog.

KILL on PANIC. A fatal panic used to burn a dedicated core until powercycle (tamago's halt is a corpse the stage-2 revoke can't even reach). Now the runtime's exit hook hands the core back to HopOS cleanly, and peers get a TCP RST at teardown instead of a connection that hangs forever.


Prebuilt, signed boot images — https://gethop.org/hopos/ for the 5-minute quickstart.

  • BOOTAA64.EFI — any UEFI arm64 box: copy to EFI/BOOT/ on a FAT USB stick, add hopos.cfg
  • hopos-rpi5.zip — Raspberry Pi 5: unzip onto the SD bootfs
  • hopos-rpi4.zip — Raspberry Pi 4: unzip onto the SD bootfs

Verify: ssh-keygen -Y verify -f allowed_signers -I hello@gethop.org -n gethop-release -s SHA256SUMS.sig < SHA256SUMS && shasum -a 256 -c SHA256SUMS

HopOS v1.3.1

Choose a tag to compare

@xinix00 xinix00 released this 19 Jul 09:14

Init jobs on the boot medium: hopos.init[]={...} in cmdline.txt (Pi) or hopos.cfg (UEFI) seeds jobs on a clean boot — one compact-JSON job per entry, same schema as the jobs API, repeatable. A standalone node without S3 always boots clean and thus always comes up with exactly this baseline: a fully self-contained node on a stick. With S3, entries seed the first clean boot only.

HopOS v1.3.0 — sharegroups

Choose a tag to compare

@xinix00 xinix00 released this 19 Jul 08:52

Cooperative core sharing, strictly opt-in. A sharegroup packs apps you explicitly name onto a shared pool of whole cores: members hand the core over when idle (explicit yield — no timer, no preemption), each still inside its own stage-2 cage with its own network stack. Sharing never happens involuntarily — ungrouped apps keep the full whole-core guarantee. Small boards now fit more apps than cores.

Prebuilt signed images attached below.

HopOS v1.2.2

Choose a tag to compare

@xinix00 xinix00 released this 18 Jul 16:14

Per-app CPU% — derived from the idle-time signal each app already publishes on its control page, averaged over a 5s window into a docker-style cpu_percent (SMP-normalized). The idle governor now counts actual idle time instead of wake ticks, making the measurement noise-immune on real hardware. Completes the per-task observability set: memory draw, temperature, CPU utilization.