Posts

Showing posts with the label QSOE

QSOE project v0.1 released

The first QSOE release, v0.1, is out. It bundles both kernel variants, the boot loader, the userspace, and libc into a single numbered drop, and consists of the following components: QSOE/N v0.17 , with the custom "Skimmer" kernel. QSOE/L v0.14 , which works together with seL4 version 15. mr-bml v0.5.1 , a GRUB-derived boot loader with support for Multiboot 3, RISC-V Linux-style kernels, and kernels with an EFI stub. quser v0.5 , offering an mksh-based shell (qsh). libc v0.6 . The two variants share the same userspace above the seam: quser, qsh, and libc are identical, with only taskman and libc.so differing per kernel. That shared userspace is the whole point — one QNX-compatible environment over two very different microkernels. The milestone behind this release is on the QSOE/L side: it now boots from NVMe storage to an interactive login shell on the SiFive Unmatched (FU740). Spawning the first program off a mounted disk had exposed a pair of deadlocks — taskman blocked ...

QSOE/L: The first spawn from real storage

The last post ended with QSOE/L still in the emulator, and the next job named in plain words: carry the image across to the Unmatched and find out which of my QEMU assumptions were lies. The image went across. It got further than I'd have guessed — far enough to bring up the PCIe root, raise devb-nvme over real DesignWare MSI, spin up the Samsung NVMe, and mount an on-disk filesystem off it — and then it wedged. This post is the lie it found, which turned out to be a foundational one. Not in seL4, not in the userspace, but in the seam between them. Where v0.13 stood By v0.13, QSOE/L had a storage stack. On the board the boot reached this and meant every word of it: [init] mounting /dev/nvme0n1p8 at /usr... fs-qrv: qrvfs v2, 4096 blocks, 128 inodes fs-qrv: mounted qrvfs at /usr (dev=/dev/nvme0n1p8) And then nothing. No panic, no fault report, no login prompt — a clean wedge exactly one line after a mount that had plainly worked. Three facts framed the hunt, and all three turne...

QSOE/L: the same userspace, on seL4

The three QSOE/N posts ended with a promise — the other half of the umbrella, QSOE/L, the same userspace running on seL4. This is that post. It is also, in a sense, the first post, because QSOE/L is where the whole thing began. Tomorrow is one month to the day since I started the real QSOE, and the first thing that booted was an seL4 image. QSOE/N, the from-scratch-kernel variant I wrote about first, is the younger sibling. I led with it because the milestone there was loud: a microkernel I wrote myself taking its first breath on real silicon. QSOE/L's story is quieter and, for the shared userspace, more foundational. Everything that runs on Skimmer today was made to run on seL4 first. No kernel to write On seL4 there is no kernel to write, and that is the entire point. seL4 is a verified, capability-based microkernel; the job was never to build a kernel but to build a QNX-Neutrino-shape operating system on top of one. seL4 has opinions, and the strongest of them is about IPC. It...

QSOE/N, part 3: first boot on the HiFive Unmatched

Part 2 left QSOE/N as a working operating system that had only ever run in QEMU. This post is the jump to real silicon — a SiFive HiFive Unmatched (FU740) on my desk — and the five obstacles between "boots fine in the emulator" and an interactive shell on real hardware. The recurring theme is that QEMU is generous in ways the FU740 is not. Every fix below is a thing the emulator either did for me silently or didn't model at all. Two of them I had already paid for once, on the same board, during the QRV port; the commits cite the QRV fixes by hash. That's the value of having ported QNX to RISC-V first: the bring-up obstacles on this board are not a surprise, they're a checklist. 1. The image won't load: boot-image header U-Boot's booti refused the flat binary outright — Bad Linux RISCV Image magic! . The same first obstacle QRV hit on the same board. RISC-V's Image protocol wants a specific header at the front of the kernel: a code0 that jumps over...

QSOE/N, part 2: from a kernel to an operating system

Part 1 ended with Skimmer at v0.5 — a sound microkernel with QNX-shape synchronous IPC, and nothing running on top of it. This post is the rest: how Skimmer became QSOE/N, an actual operating system with processes, a C library, drivers, and a conformance suite that passes a full lap. All of it still in QEMU; real hardware is part 3. The umbrella QSOE — "Quick and Secure Operating Environment" — is a QNX-Neutrino-style operating environment for 64-bit RISC-V, built entirely under Apache-2.0. It comes in two variants that share almost everything: QSOE/N (project NQ), the native-kernel variant, running on Skimmer. QSOE/L (project LQ), running the same userspace on the seL4 microkernel. The split is deliberately thin. The kernel differs, the system process (taskman) differs, and a small OS-dependent slice of libc differs. Everything else — the C library body, the drivers, the utilities — is shared between the two systems. That constraint shaped a lot of the decisions below,...

QSOE/N, part 1: proving the core (Skimmer v0.1–v0.5)

This is the first of three posts tracing QSOE/N from its first commit to its first boot on real hardware. This one is about the kernel alone — Skimmer — before there was any userspace to speak of. The whole point of v0.1 through v0.5 was to answer one question: is the core sound? Everything after it assumes the answer is yes. I built all of it alongside Claude Code (Opus 4.7 for this stretch, 4.8 later). The commits carry the co-author line; I'm not going to repeat it every paragraph, but the race hunts below were genuinely a two-party effort. Where the design comes from Skimmer is a from-scratch microkernel for 64-bit RISC-V, Apache-2.0, written to a QNX shape. The concurrency model is not QNX's, though — it's DragonFly BSD's. The two ideas I took are Light Weight Kernel Threads (LWKT) and message ports: per-CPU run queues with no cross-CPU locks on the hot path, and cross-CPU work expressed as messages routed through per-CPU rings rather than as foreign writes into...

How QSOE started

It was the first of April, and work on QRV — my port of QNX to RISC-V — was in full swing. A couple of weeks earlier I had put up an open petition asking QNX Software Systems and BlackBerry to re-license the historical 2007–2009 QNX Neutrino source under Apache 2.0. Around this time a thought settled in: there's a real chance it gets ignored completely. I needed a plan B. I've kept the L4 microkernel in the back of my mind for a long time. I first read about it in the early 2000s, along with its various implementations — the ones with the nutty names (Hazelnut, Pistachio), and the one with the funny name, Fiasco, from the group in Dresden. I met those people in person about ten years ago. I never really stopped thinking about L4 after that; I knew about L4Linux and the rest. And I got particularly interested when I learned about seL4. What seL4's authors did still strikes me as a genuinely novel approach: a real microkernel with a machine-checked proof of functional corr...