QSOE
A QNX-inspired operating system with selectable kernels.
News: QSOE 0.2 is out — a text console on the screen with a USB keyboard on it, a writable filesystem, and QSP transparent distributed networking (September 2026). What's new in 0.2 →
QSOE ships in two variants that share one userspace and one build system. QSOE/N runs on Skimmer, a microkernel written from scratch for this project (SMP by design); QSOE/L runs on seL4 as its kernel.
Both variants, when compiled, offer the kernel and initrd files directly usable in
e.g. U-Boot loader. The userspace is 100% identical across
both variants; the only parts produced per-kernel are taskman, the task
manager, and libc.so — the C library, which is around 85% shared at the source
level and diverges only at the thin layer where it meets the kernel.
The design follows the QNX Neutrino tradition: a small kernel with everything else in userspace, synchronous message-passing IPC, and the resource-manager model for services.
QSOE targets 64-bit RISC-V (RV64, Sv39) on the SiFive HiFive
Unmatched (FU740) and the SpacemiT K3 Pico-ITX, with QEMU used for day-to-day
development. Both QSOE variants boot on real hardware; the K3 — RVA23-class, sixteen harts,
pure AIA — is QSOE/N only for now, being too new for seL4. Released under Apache-2.0.
Downloads
QSOE can be built from source or installed from pre-built binaries. Ready-made images for each release are published at github.com/qsoe-dev/dl (current release: 0.2). The files are:
- The Skimmer microkernel — the kernel of the QSOE/N
variant. A raw binary image, loaded by the bootloader (or QEMU) together with the userspace
package below. Skimmer is linked once per board, so take the one for yours:
skimmer-sifive.bin(HiFive Unmatched),skimmer-k3.bin(SpacemiT K3), orskimmer-qemu.bin(QEMUvirt). What the board decides is the load address; the platform itself is read from the device tree at run time. So the QEMU and Unmatched images are byte-for-byte identical — either name gets you the same kernel — while the K3, whose DRAM starts at 4 GiB, is linked for its own address and its image is its own. Take the K3's across that line, in either direction, and the machine loads a kernel and then does nothing recognizable. modpkg.cpio— the module package: the shared QSOE userspace (taskman,init, the C library, the shell, the file manager, drivers and utilities) as a CPIO archive. One archive for every board and both variants. QSOE/N boots it as an initrd alongsideskimmer-<board>.bin.qsoe-l-qemu.elf— the QSOE/L variant (on the seL4 kernel) as a single, self-contained ELF for the QEMUvirtmachine. It bundles the elfloader, the seL4 kernel, taskman and the userspace together — nothing else is needed to boot.qsoe-l-sifive.elf— the same QSOE/L image, built for the SiFive HiFive Unmatched (FU740) board. There is no K3 equivalent: that SoC is too new for seL4.mrbml-riscv64.efi— mr-bml, QSOE's own bootloader (an EFI application for RISC-V). It can load either variant and drives the boot menu on real hardware.nvme.img.gz— a ready-to-run, self-booting QEMU disk image (GPT). Its EFI partition holdsmr-bml, and an on-disk root holds both kernels — so QEMU boots straight to the mr-bml menu, no-kernelneeded. The fastest way to see QSOE run; see Running under QEMU below.virtio.img.gz— a companion root disk used only when running QSOE/L under QEMU (stock seL4 predates the interrupt controller QEMU's NVMe needs, so it mounts its root from a virtio disk instead). Not needed for QSOE/N or for real hardware.
In short: to run it in QEMU, grab nvme.img.gz
(plus virtio.img.gz for QSOE/L) and see Running under QEMU.
To put it on real hardware, you need mrbml-riscv64.efi
plus the kernels — QSOE/N uses skimmer-<board>.bin +
modpkg.cpio,
QSOE/L uses one of the qsoe-l-*.elf images — and see
Installation.
Running under QEMU
The quickest way to see QSOE run — no hardware, no -kernel juggling. The
nvme.img download is a self-booting UEFI disk: QEMU's firmware runs
mr-bml from it, and mr-bml's menu starts either variant straight off the disk.
You need
qemu-system-riscv64— version 11.0.1 or newer for QSOE/N (its NVMe needs the AIA interrupt controller).- edk2 RISC-V UEFI firmware — on Debian/Ubuntu, the
qemu-efi-riscv64package. - The launcher
run-nvme.shfrom the os repository — it wraps the right QEMU machine, firmware and disks for each variant, so you don't have to.
Run it
# unpack the image(s) — add virtio.img.gz only if you want QSOE/L gunzip nvme.img.gz virtio.img.gz # point the launcher at them and pick a variant from its menu NVME_IMG=./nvme.img VIRTIO_IMG=./virtio.img ./run-nvme.sh
Pass n or l to skip the menu (./run-nvme.sh n). The script
selects the matching QEMU machine automatically — QSOE/N on the AIA machine with an NVMe root,
QSOE/L on the PLIC machine with the virtio root disk. The mr-bml menu and the system console
both appear on your terminal; choose a variant and it boots to a login: prompt.
Log in as root with password QSOE.
Installation
Real hardware, real disk. QSOE 0.2 boots on the SiFive HiFive Unmatched (FU740) and on the SpacemiT K3 Pico-ITX; on the K3, QSOE/N only. This assumes a board already running Linux — you'll be placing files on its existing EFI and boot partitions, so familiarity with the board's firmware is expected.
The boot model is simple: mr-bml lives in the EFI System Partition; it reads its menu and the kernels from an ext2/3/4 partition; the chosen variant then mounts its own root from a fs-qrv partition.
Steps
- Copy
mrbml-riscv64.efiinto your ESP asEFI/BOOT/BOOTRISCV64.EFI(the UEFI removable-media path), or register it withefibootmgras a boot entry. - On your boot/root filesystem, create
/boot/qsoe/and copy the kernels there: your board'sskimmer-<board>.bin+modpkg.cpiofor QSOE/N,qsoe-l-sifive.elffor QSOE/L. - Create
/boot/mr-bml/mr-bml.cfgwith one entry per variant — for example:
# /boot/mr-bml/mr-bml.cfg — adjust the mainfs= partition to your disk
menuentry 'QSOE/N (Skimmer)' {
kernel /boot/qsoe/skimmer-sifive.bin mainfs=/dev/nvme0n1p8
modpkg /boot/qsoe/modpkg.cpio
}
menuentry 'QSOE/L (seL4)' {
kernel /boot/qsoe/qsoe-l-sifive.elf mainfs=/dev/nvme0n1p8
}
The mainfs= device names the partition holding the QSOE root filesystem (fs-qrv) —
set it to whichever partition you've devoted to QSOE on your board. On real hardware there is
no QEMU virtio split: both variants drive the NVMe disk directly.
Building from source
QSOE is built with a riscv64-linux-gnu- cross toolchain (rv64gc) and a stock
make; QEMU is handy for testing. The umbrella repository orchestrates the build and
pulls in the component repositories that match its release tag.
git clone https://gitlab.com/qsoe/os cd os make prepare # fetch the components for this tag (see component.list) make # build both variants: QSOE/N, then QSOE/L make dist # optional: the QEMU disk images (nvme.img.gz, virtio.img.gz)
QSOE/L additionally shallow-clones the seL4 kernel during make prepare. The build
produces exactly the files on the Downloads list. The whole tree is Apache-2.0; the source
lives under gitlab.com/qsoe.
Documentation
The QSOE manuals, published as PDF alongside the releases:
Design.pdf— the architecture: the two-kernel model, taskman, the IPC and resource-manager design.UserGuide.pdf— installation, the shell, the basic commands, the text editor and the utilities.ProgrammingBook.pdf— programming for QSOE, including the Resource Server Framework chapter.AppPortingGuide.pdf— porting Unix (and QNX) software to QSOE: what to account for — nofork(), nobrk(),select()viapoll(),ioctl()viadevcontrol(), and the rest.Networking.pdf— QSP, the transparent distributed networking: stations and call signs, circuits and transactions, and why a resource manager reached across the wire is never told that anything happened.LibcReference.pdf— the C library reference, new in 0.2. A delta rather than a complete reference: the functions libc gained since 0.1, grouped by subject, in the entry shape a QNX reader already knows.
Roadmap
It is often said that the Linux kernel has no roadmap. QSOE does — the releases that carry it from today's 0.2 to 1.0 are mapped out, feature by feature. A working plan, not a contract: milestones shift as the work reveals what is really next, and they have.
1.0 is a capability rather than a compatibility claim: a RISC-V real-time operating environment with a stated, measured worst-case latency, sustained for a week under full load across three different boards, able to rebuild itself, with a documented porting path from QNX and POSIX. Four criteria, each pass or fail.
0.1— Foundation and login. Both kernels boot to an interactive shell on one shared, dynamically linked userspace; read-onlyfs-qrvat/usr, spawn from disk, getty and login. Sources opened under Apache-2.0. (released June 2026)0.2— Video console and QSP. A text console on a handed-over graphics controller with a USB keyboard on it, and QSP transparent distributed networking over a shared descriptor ring. The system stops being something observed over a serial cable and becomes something a person sits at. (current — release notes)0.3— Writable filesystem.qrvfsgains writes:O_CREAT/O_TRUNC, create and unlink,realpathand symlink resolution; QSOE/L moves to the July 2026 seL4 release. A disk that is only read can afford to be approximate; a disk that is compiled on cannot — and 0.6 compiles on it.0.4— Sound out:deva-hdmi. HDMI audio brought up as a device. Audio is the instrument for every measurement from here to 1.0 — a dropped buffer is audible long before it is visible — which is why it comes this early.0.5— The real-time package. Priorities, interrupt service threads, priority inheritance and bounded paths end to end: up to N hard-real-time tasks on an N-CPU system, with every step between an interrupt and the thread that services it accounted for.0.6— Self-hosting. The compiler runs on the target, against the writable filesystem, and rebuilds QSOE from source on the board.0.7— Hardening, and the first long run. Leak hunts, lifetime and teardown, error paths nobody has taken — everything the soak will break, broken deliberately first. Then 24 hours of continuous audio under sustained multi-core load with live NVMe and Ethernet traffic.0.8— The number. The week-long soak, and the worst-case latency figure it earns — published with its conditions, its methodology and its instrumentation, so the result can be reproduced and argued with from outside the project.0.9— The porting set. A named set of QNX and POSIX programs recompiled and running, with two documented edits:fork→posix_spawnandselect→poll.1.0— QSOE. All four criteria met on every supported board.
Throughout: both kernels advance together
— the userspace is identical by construction, NQ leads on the real-time path and LQ
follows where the seam can express it. Platforms at 1.0 are the SiFive Unmatched
(FU740), the SpacemiT K3 Pico-ITX, the StarFive VisionFive 2 and QEMU
virt — three different SoCs with three different Ethernet controllers,
speaking one protocol to each other. Packaging is deliberately not a 1.0 milestone;
documentation is a release gate.
Other projects
Earlier and adjacent work.
- GateMate PC — a personal computer built on the Cologne Chip GateMate FPGA.
- GateMate System/359 — an IBM S/360-inspired FPGA implementation of a computing system, with I/O channels and a powerful macroassembler.
- QRV — a QNX port to RISC-V (historical); fed hardware bring-up lessons into QSOE/N.
Services
Consulting and development in low-level and systems software.
- Microkernel-based operating systems
- System libraries and low-level runtime
- Virtualization for real-time applications
- RISC-V systems bring-up
- AI-assisted development for FPGAs
Engagements range from focused bring-up work to longer-term architecture and implementation. Get in touch to discuss scope.
About
QSOE Systems is the independent practice of Yuri Zaporozhets, a systems software developer with 25+ years of experience building low-level software — kernels, operating systems, runtimes, and the hardware bring-up underneath them.
Contact
Email is the best way to reach me.