Skip to content

Releases: jordanhubbard/RubyOS

RubyOS v0.4.0

Choose a tag to compare

@jordanhubbard jordanhubbard released this 22 Sep 00:33

RubyOS v0.4.0

The desktop gets real type

Every string the GUI drew went through an embedded 8x8 bitmap font, one
SDL_FillRect per lit pixel, ASCII only. SDL_ttf had been available across the
bridge the whole time and nothing used it.

RubyOS::GUI::Text now routes every draw_text through TTF, caching rendered
runs host-side and falling back to the bitmap face on a host with no usable
font. Menlo at 14pt advances exactly 8 pixels — the same grid the bitmap font
used — so no layout had to move. The literal 8s that assumed that grid are
gone regardless, replaced by the measured advance, because the next host's font
will not be Menlo. A proportional face is refused outright rather than laid out
on a column grid it does not honour.

Frames got cheaper in the process: one cached blit per string, against one fill
per lit pixel. Visual goldens pin themselves to the bitmap face so their tile
hashes stay reproducible on a host that ships DejaVu instead of Menlo.

A dock with icons, and a desktop with a size

The dock painted text labels in boxes. It now paints centred square icons with
a hover label and a running-app pip. RubyOS::GUI::Icons declares each icon as
rectangles and lines on a 48x48 grid and renders it at whatever edge the dock
asks for, so a compact desktop gets a genuinely smaller icon rather than a
shrunken one. They are drawn rather than loaded because kernel sources are
embedded as a C string literal and have to stay 7-bit ASCII, which would make a
baked-in image cost several times its own size. The debug-grid wallpaper is now
a banded gradient.

The desktop was also fixed at 1024x768. It now treats that as a request:
display.open reports the framebuffer the host actually created and the guest
adopts it, which RUBYOS_DESKTOP_SIZE=1920x1080 make run-gui steers from the
host side. Window geometry follows, scaling against a 1024x768 reference and
capped at 2x, with anchored children riding the same relayout path a
resize-grip drag uses. At or below the reference it changes nothing.

The editor, launcher and inspector were still sized for a 480x300 screen and
clipped source mid-line on a full desktop. They now open at sizes that fit
their contents.

Two allocator defects, one of them longstanding

rubyos-arm64-gui-smoke had been failing before this release. The reported
symptom was CRuby's [FATAL] failed to allocate memory, and the heap was not
the problem — it had over a hundred megabytes free at the moment it died.

mmap kept live mappings in a fixed table of 128 records. CRuby's GC takes a
mapping per heap page, so the table filled after a few megabytes of object heap
and mmap began returning MAP_FAILED with memory still plentiful. CRuby
reports that as exhaustion and aborts, which is why the failure looked like a
heap problem and why it was intermittent. The table now holds 16384 mappings.
Enlarging the guest heap does not help and enlarging it far enough to satisfy
the speculative 384 MiB allocation CRuby makes at startup actively hurts,
because the reservation then succeeds and consumes the heap.

Separately, the virtio-console bridge transport allocated a DMA buffer for
every message it wrote and never freed it, leaking a page per bridge message.
It now holds one bounce buffer and grows it on demand. The native-TCP transport
was never affected, which is why the desktop acceptance suite stayed green
throughout.

Bridge payloads also move by memcpy now rather than a Ruby call per byte.
arm64 had no bulk DMA primitive; it does now, and both architectures gained the
read direction.

Everything from the unreleased 0.3.2

This release also carries the work prepared as 0.3.2, which was never tagged:
the full PythonOS behaviour surface expressed in Ruby, with complete system
applications, thirteen Ruby-focused demonstrations and five playable games, all
rendered and compared in frozen ARM64 and x86_64 guests.

That work brought responsive anchored layouts, resizable windows, app-aware
menus, persistent dock pins and shortcuts, shared file choosers, bounded
host/guest file transfer, transactional source editing and live Ruby object,
Fiber, driver and heap inspection. F5 opens the focused application's archived
Ruby source and replaces its class only after validation succeeds. The serial,
TCP and graphical consoles share one stateful shell with syntax-aware multiline
evaluation, completion, VFS-persistent history and streaming TCP file transfer.
RubyOS::App remains the supported backend-neutral application class library;
see docs/applications.md.

Release validation

The release commit is accepted independently on Linux ARM64, Linux x86_64 and
Apple Silicon macOS. ARM64 and x86_64 frozen guests boot the expanded console,
network stack and native-TCP desktop, while architecture-specific visual
goldens cover every application and the interaction captures. Both golden sets
were refreshed for the new dock and wallpaper and then re-verified in a
separate run, since a refresh passes by construction.

Pins RemoteOS-SDL 0.3.0.

RubyOS v0.4.0.

Release validation

  • Linux and macOS workflow: 35670452984
  • Source commit: c657ad74448bf12cd011648548eec66201b26418

RubyOS v0.3.1

Choose a tag to compare

@jordanhubbard jordanhubbard released this 17 Sep 01:00

RubyOS v0.3.1

A fresh checkout now knows how to become a development machine

make install is the supported bootstrap entry point on ARM64 and x86_64
macOS, Debian/Ubuntu Linux and Windows WSL2. It installs the SDL, FFmpeg, QEMU,
Ruby build and filesystem dependencies through Homebrew or apt, initializes
the shared RemoteOS-SDL submodule, starts Docker where the host permits it and
prepares the native-host cross-toolchain image.

The regular build also initializes the display-service submodule if an
existing clone omitted it. Linux container commands can fall back through
sudo immediately after Docker installation, rather than requiring a logout
before the first RubyOS build. WSL2 keeps the same build surface on both host
architectures; interactive windows require WSLg, while headless tests do not.

ARM64 RAM is RAM now

The ARM64 bootstrap establishes an EL1 identity map before CRuby starts. QEMU
MMIO below 1 GiB retains device-memory semantics, while RAM beginning at
0x40000000 is normal write-back memory. This fixes the alignment exceptions
previously raised by valid CRuby scalar and SIMD accesses during ractor and
Prism initialization.

The same translation setup runs on application processors. Console boot, the
persistent desktop, native-TCP GUI/media, and four-core worker paths now pass
on ARM64. The x86_64 console and desktop paths remain covered independently.

The interactive desktop fails clearly instead of hanging

Pointer clicks on text fields and other non-button views no longer arrive as
synthetic button events. This fixes the guest exception previously triggered
by clicking the Terminal or Editor after the desktop reported itself ready.

The public GUI supervisor now watches the guest serial log for fatal markers.
If the guest raises unexpectedly, it terminates the checkout's QEMU and SDL
children and returns a failing status with the diagnostic log path instead of
leaving an apparently live window forever.

Installation is part of the release gate

Installer routing is tested for macOS, Debian/Ubuntu Linux and WSL2 on both
ARM64 and x86_64. Release CI now invokes make install instead of maintaining
a second handwritten dependency list, so the documented first-run path and
the path used to create release artifacts cannot silently diverge.

RubyOS v0.3.1.

Release validation

  • Linux and macOS workflow: 35166743543
  • Source commit: e13e8541cda7596799d4659b635d497fbc9b4be6

RubyOS v0.3.0

Choose a tag to compare

@jordanhubbard jordanhubbard released this 16 Sep 01:31

RubyOS v0.3.0

Ruby gets a studio, not a commemorative chipset

RubyOS now has block-scoped SDL resources, 2D scenes, perspective 3D meshes,
seekable property animation, PCM composition, video playback and audiovisual
recording. Ruby objects describe what happens. RemoteOS-SDL handles host
rendering and codecs. Nobody has to pretend a copper list is a personality.

The old chipset hierarchy is removed. Invaders and Snake retain their gameplay
while rendering through ordinary bitmap objects. The desktop's Media Workbench
replaces its hardware-homage laboratory.

Make something, then play it back

The source-built CRuby 4.0.6 runtime remains the language engine. Run
examples/studio.rb for an animated cube with text, or examples/movie.rb
to record a two-second audiovisual scene, export it as Matroska and play it.
The multimedia guide supplies complete launch commands.

Studio#record advances its timeline in fixed steps. A Ruby audio callback
supplies PCM per frame; the service encodes MPEG-4 video and muxes both tracks.
Video#play, pause, seek and tick expose host audio-clocked playback.
Resources close with their blocks; drawing batches obey negotiated limits and
report errors. Small pleasures, such as not leaking a font every frame.

Platforms and honest limits

Hosted integration and ARM64/x86_64 bare-metal native-TCP tests cover 3D,
export and playback. Linux ARM64, Linux x86_64 and macOS ARM64 release gates
use the pinned shared service. Linux bundles retain both guest architectures.
Windows uses WSL2, not a native Windows kernel build.

The framework is not a finished video editor. Clip bytes cap at 16 MiB,
audio predecode/export at 60 seconds, and export uses even dimensions up to
2048 with fixed integer frame rates. OpenGL has readback and a software fallback;
textures, lighting and streaming remain outside this release. See the guide
for ownership, clock precision, codec and transport boundaries.

Executive summary: a Ruby-focused multimedia foundation, two real guest CPU
architectures, and substantially fewer reasons to role-play a 1980s chipset.
RubyOS v0.3.0.

Release validation

  • Linux and macOS workflow: 35042830174
  • Source commit: 51d06ce09874b45229cb3d0717f52e422a0caad0

RubyOS v0.2.2

Choose a tag to compare

@jordanhubbard jordanhubbard released this 15 Sep 23:54

RubyOS v0.2.2

An operating system, now with commands humans can remember

RubyOS has achieved the previously unimaginable: make, make run,
make run-gui, and make stop. The specialized targets still exist, but
memorizing the entire bring-up history is no longer an entrance examination.
make help introduces the everyday commands; the advanced build guide keeps
the architecture and device experiments available to their devoted audience.

The desktop now stays open. This astonishing innovation replaces the smoke
test's scripted visit with a persistent, interactive RemoteOS-SDL session.
Terminal, Files, Inspector, Editor, games, and the other Ruby applications
share the existing compositor and native TCP transport.

A Ruby process supervisor owns each checkout's console or desktop session.
It rejects duplicate launches, coordinates shutdown, and stops its own child
processes. Stopping your OS need not involve hunting unrelated processes
with a particularly optimistic kill command.

make clean preserves the expensive source-built Ruby caches and persistent
disk. make cleanall removes build caches when you actually mean it.
make package builds local release media; it does not publish a release.

Platforms and validation

The everyday commands now select the host CPU, with TARGET_ARCH=arm64 or
TARGET_ARCH=x86_64 overrides. x86_64 gains the real console, writable ext2,
DHCP/DNS/TCP, HTTP and persistent native-TCP desktop through modern VirtIO
PCI. The same Ruby network and filesystem code serves both architectures.
The Docker builder runs natively on either host CPU. Owning an Intel machine
no longer enrolls you in an unsolicited ARM emulation appreciation course.

The broader desktop gate also caught an x86 libc rounding routine that
compiled into an infinite self-jump. It now rounds numbers instead of
contemplating them forever, with guest rounding and audio-synthesis tests.

Linux ARM64 and x86_64 bundles include persistent desktop media alongside
the full ARM64 ELF and x86_64 ISO variants. macOS ARM64 bundles remain
hosted-runtime packages, not proof of macOS bare-metal guest parity.
CRuby 4.0.6 is still built privately from source; RemoteOS-SDL remains 0.1.1.

Lifecycle regression tests exercise the real console, a persistent headless
desktop, duplicate rejection, and scoped shutdown. The release workflow
requires local Linux validation and green ARM64 Linux, x86_64 Linux and macOS
CI, then checks and
publishes the CI-produced bundles. Host SDL dependencies remain required;
WSL2/WSLg is not claimed as verified.

Executive summary

Fewer commands to learn, a desktop that stays, and cleanup that remembers
how long Ruby took to compile. An outrageous outbreak of approachability.

RubyOS v0.2.2

Release validation

  • Linux and macOS workflow: 35035743726
  • Source commit: b7b83b118f98a2f906233c4ce1ad736ee4043b3c

RubyOS v0.2.1

Choose a tag to compare

@jordanhubbard jordanhubbard released this 15 Sep 20:43

RubyOS v0.2.1

Ruby deserves a first checkout that actually works

This patch release makes recursive cloning and SDL prerequisites explicit,
and tells an incomplete checkout how to initialize its shared service.
Headless desktop tests now set the service's actual REMOTEOS_SDL_MODE
variable. A lovingly named variable that nobody reads is not configuration.

Native input probes now announce readiness after device initialization; host
tests wait for that signal before injecting keyboard and mouse events. This
removes a race where a fast test could send input before VirtIO was listening.
The release script explicitly propagates failed CI checks before downloading
artifacts.

RubyOS pins RemoteOS-SDL 0.1.1, aligned with PythonOS 0.4.1. Protocol v2 and
Ruby's class hierarchy, Fibers, live editing, introspection and bare-metal TCP
desktop remain unchanged. No new Ruby VM or runtime is quietly substituted:
CRuby 4.0.6 is still built from source, never taken from old system packages.

Release media and validation

Linux ARM64 and macOS ARM64 bundles include the private Ruby runtime and native
SDL service. The Linux bundle also contains ARM64 ELF variants and x86_64 ISO
variants. DGX Spark passed the complete Linux parity gate, including networking,
storage, native TCP desktop, input, audio, SMP and debugger checks. An extracted
bundle ran with its relocated Ruby runtime.

The release script requires green Linux and macOS CI, verifies both bundles'
checksums, and publishes the CI-produced artifacts. Host SDL dependencies are
still required; WSL2/WSLg remains unverified. The HTTP service is Rack-shaped,
not a claim that Rails boots today, and remote protocol v2 still needs a
trusted network or authenticated tunnel.

Executive summary

A cleaner installation, correct headless tests, and the same intensely Ruby
system sharing one host service with PythonOS. Less setup archaeology, more
objects worth inspecting.

RubyOS v0.2.1

Release validation

  • Linux and macOS workflow: 35019593679
  • Source commit: 6b7a7a7877ce341c55d009b336b67096efd4bc8d

RubyOS v0.2.0

Choose a tag to compare

@jordanhubbard jordanhubbard released this 15 Sep 07:23

RubyOS v0.2.0

Ruby has stopped sharing its SDL homework

RubyOS and PythonOS now speak one deliberately breaking RemoteOS protocol v2
to one shared RemoteOS-SDL service. The copied C companion is gone. Ruby queues
response-free drawing operations as a bounded render batch, then
frame.commit presents and brings input home in the same round trip. The host
reports wire volume, dropped events, audio depth, and per-operation SDL time,
which is rather more actionable than staring sternly at a window.

More importantly, this path runs from bare metal. CRuby 4.0.6 acquires DHCP
through RubyOS's VirtIO NIC, accepts the display service through RubyOS's TCP
listener, segments the stream below Ethernet MTU, and drives the entire desktop
without a QEMU character-device shortcut. The old VirtIO-console route remains
an independently useful device path, not a compatibility facade.

The live system is aggressively Ruby

The desktop now includes Live Ruby and Ruby Inspector. Application source lives
in the RubyOS VFS, compiles into an anonymous Module, and replaces the registry
entry only after evaluation succeeds. A syntax error or failed evaluation
leaves the running application intact. RubyOS::Live::ClassEditor similarly
patches real instance methods and restores their prior definitions if the
transaction raises.

The introspection API reports bounded, cycle-aware object graphs; class
ancestors, methods, and constants; heap leaders; scheduler Fibers; and live
device/driver bindings. This is not a generic remote-debug facade painted red.
It is Ruby's object model used as an operating-system workbench.

A web server, with honesty included

RubyOS now parses HTTP, routes with blocks, creates a Rack-shaped environment,
and serves [status, headers, body] responses from its bare-metal TCP stack.
The release gate boots the kernel and curls it through QEMU forwarding.

That is a meaningful path toward Rack and, eventually, Rails. It is not a claim
that Rails runs today. Rails still expects a much larger stdlib and gem surface,
stronger socket/thread contracts, persistent services, databases, clocks, and
native extensions. RubyOS will earn those layers instead of adding a logo and
hoping nobody asks for Active Record.

ISeq: cache, not constitution

The source-built Ruby can freeze and reload instruction sequences, and the new
tool records engine, version, revision, platform, source hash, and binary hash.
MRI itself says those binaries are not portable and its loader does not verify
hostile input. Our build interpreter is aarch64-linux; the kernel is
aarch64-none. Therefore source remains the boot format and ISeq remains an
exact-build, trusted cache experiment until the target itself can produce it.

Builds and artifacts

  • Linux CI builds source Ruby and executes hosted plus ARM64/x86_64 bare-metal
    parity, including native-TCP desktop and HTTP server gates.
  • macOS CI builds Ruby from source, runs the hosted/runtime/RemoteOS suites, and
    emits its own release bundle.
  • Windows continues through the Linux contract under WSL2.
  • Bundles include the source-built Ruby runtime and canonical remoteos-sdl
    binary, never a distribution Ruby package.

Executive summary

RubyOS 0.2.0 has one shared, measured host-device boundary; a native TCP remote
desktop; live Module/class surgery with rollback; an object/Fiber/driver
inspector; and an HTTP server running where an operating system normally lives.
It remains source-built CRuby all the way down, because ancient package managers
have contributed enough to this experiment already.

Download RubyOS v0.2.0

Release validation

  • Linux and macOS workflow: 34940016714
  • Source commit: 17ea8b1a465c5a75143ee93a0ba4737d853ce1e3

RubyOS v0.1.0

Choose a tag to compare

@jordanhubbard jordanhubbard released this 15 Sep 04:46

RubyOS v0.1.0

Ruby has taken the machine

RubyOS 0.1.0 is the first public release of an operating system in which CRuby
is not a scripting accessory politely waiting above a conventional kernel.
CRuby 4.0.6, built from pristine upstream source because distribution packages
have enjoyed quite enough leisure, is the kernel runtime.

Assembly and a deliberately small C substrate establish the machine. Then Ruby
objects take over scheduling, memory, devices, filesystems, network protocols,
the desktop, applications, games, and the suspiciously enjoyable fake-classic
chipset laboratory. This is objects all the way down, until the MMIO register
refuses to respond to #map.

Two architectures, one very Ruby operating system

  • ARM64 boots through EL1, GIC timers, PSCI SMP, and native VirtIO block,
    network, keyboard, pointer, and sound devices.
  • x86_64 boots through GRUB and long mode with IDT/PIT interrupts, PS/2 input,
    Intel HDA DMA, and APIC INIT/SIPI worker bring-up.
  • Both run the same source-built CRuby 4.0.6 and embedded Ruby kernel classes.
  • CRuby remains safely on its GVL-owning bootstrap CPU while Ruby dispatches
    explicitly C-safe jobs to native application-processor mailboxes. We chose
    correctness over the traditional concurrency benchmark of "it worked once."

A desktop Rubyists can actually poke

The SDL companion is a remote hardware device, not the author of the scene.
Ruby owns the compositor, windows, focus, hit testing, widgets, dock, menu,
Terminal, Editor, Files, Monitor, Clock, Settings, Image Viewer, Invaders, and
Snake. PNG/JPEG decoding, SDL_ttf fonts, canonical input events, PCM mixing,
and framebuffer captures all cross the same small transport boundary.

The chipset workbench adds dual playfields, display lists, Copper operations,
sprites, blits, and four-channel Paula-style audio. Modern computers are very
powerful, so naturally we used one to lovingly reconstruct the constraints
that made old computers interesting.

Storage, networking, and debugging without hand-waving

Ruby implements writable ext2—including sparse files and double-indirect block
traversal—over a native VirtIO block queue. The network stack handles Ethernet,
ARP, IPv4, ICMP, UDP, DHCP, DNS, and TCP, including simultaneous remote Ruby
console sessions.

Every native run retains an independent serial failure plane. Debug sessions
add QMP control, GDB-remote symbols, SDL captures, guest round-trip timing, and
host service-time metrics. make parity tests the whole arrangement on ARM64
and x86_64 because "the architecture is elegant" is not a boot log.

Builds and artifacts

  • Linux CI builds and executes the complete bare-metal matrix, then packages
    the source-built host runtime, SDL bridge, ARM64 ELFs, x86_64 ISOs, and ext2
    disk image.
  • macOS CI builds CRuby from source, runs the hosted Ruby kernel and SDL suite,
    and packages a self-contained Apple Silicon host bundle.
  • Windows development uses the Linux contract under WSL2. There is no pretend
    native Windows port hiding behind a green YAML rectangle.

Executive summary

RubyOS boots real machines, drives real emulated devices, presents a real
desktop, and puts idiomatic Ruby objects where an operating system normally
puts several million lines of somebody else's opinions. Version 0.1.0 is the
point where the experiment becomes a release—and the burden of explaining why
your language cannot implement a NIC driver returns to everyone else.

Download RubyOS v0.1.0

Release validation

  • Linux and macOS workflow: 34928690945
  • Source commit: d015aa0f690d3dad97fce58b4df2ba9fc34a029e