QSOE
A QNX-inspired operating system with selectable kernels.
News: QSOE 0.4 is out — sound on every board and both kernels, clean beside a full test suite; the base system installed as a package, with a package manager and a C compiler that runs on QSOE; one C library and one boot archive for both kernels, and QSOE/L on the K3 (October 2026). What's new in 0.4 →
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.
Each variant is a kernel file and one boot archive, modpkg.cpio, which is the
same file for both; QSOE's own boot loader, mr-bml, starts either from one
menu. The userspace is 100% identical across both variants, down to
libc.so, a single binary; the only parts built per kernel are
taskman, the task manager, and libqsoe.so, the library of the
native calls — channels, messages, pulses, threads — at the thin layer where
the system 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), the StarFive VisionFive 2 (JH7110) and the
SpacemiT K3 Pico-ITX, with QEMU used for day-to-day development. Both variants boot on every
board; on the K3 — RVA23-class, sixteen harts, pure AIA — QSOE/L runs on
k3sel4, a port of seL4 to the SoC.
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.4), with a SHA512SUMS file to check
them by. The files are:
nvme.img.gz— a ready-to-run, self-booting QEMU disk image (GPT): mr-bml in its EFI partition, both kernels and the boot archive beside it, and a system volume with the base system installed as a package. 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.run-nvme.sh— the QEMU launcher for the two images.modpkg.cpio— the boot archive: taskman,init, the C library, the shell, drivers and utilities as a CPIO archive. One archive for every board and both variants: it carries both taskmen, and each kernel takes its own.- The Skimmer microkernel — the kernel of QSOE/N,
linked once per board, so take the one for yours:
skimmer-sifive.bin(HiFive Unmatched),skimmer-vf2.bin(StarFive VisionFive 2),skimmer-k3.elf(SpacemiT K3;skimmer-k3.binis the same kernel as a flat image), 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, while the K3, whose DRAM starts at 4 GiB, and the VisionFive 2, whose firmware still holds the low end of its RAM, are each linked for their own address. Take one across those lines, in any direction, and the machine loads a kernel and then does nothing recognizable. - The seL4 kernel — the kernel of QSOE/L, booted by
mr-bml's
multiboot3command withmodpkg.cpioas its module:sel4-sifive.elf,sel4-vf2.elf,sel4-qemu.elf, andsel4-k3-15.elffor the K3 (k3sel4, on fifteen harts). mrbml-efi-riscv64_1.0_riscv64.deb— mr-bml 1.0, QSOE's own bootloader (an EFI application for RISC-V), as a Debian package for the board itself. It loads either variant and drives the boot menu on real hardware. A package rather than a bare binary because the image has to know where its configuration lives, which differs per machine:mrbml-installassembles it on the board, for that board's volume.
In short: to run it in QEMU, grab nvme.img.gz
(plus virtio.img.gz for QSOE/L) and run-nvme.sh, and see
Running under QEMU. To put it on real hardware, you need
the mr-bml package, modpkg.cpio and your board's kernels —
skimmer-<board> for QSOE/N, sel4-<board>.elf for
QSOE/L — 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.sh, among the downloads (and in 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 name the variant: n for QSOE/N, l for QSOE/L NVME_IMG=./nvme.img VIRTIO_IMG=./virtio.img ./run-nvme.sh n --uefi NVME_IMG=./nvme.img VIRTIO_IMG=./virtio.img ./run-nvme.sh l --uefi
The variant is not optional: it selects the QEMU machine — QSOE/N on the AIA machine
with an NVMe root, QSOE/L on the PLIC machine with the virtio root disk — so pick the
matching entry in mr-bml's menu. --uefi boots through the distribution's edk2.
The mr-bml menu and the system console both appear on your terminal, and the chosen variant
boots to a login: prompt. Log in as root (password
QSOE) or user (password skimmer).
Installation
Real hardware, real disk. QSOE 0.4 boots on the SiFive HiFive Unmatched (FU740), the StarFive VisionFive 2 (JH7110) and the SpacemiT K3 Pico-ITX, both variants on each. 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
- On the board's Linux,
apt install ./mrbml-efi-riscv64_1.0_riscv64.deband runmrbml-install: it reads the label of the filesystem/bootis on, assembles an image that finds that volume by label, and places it in the ESP atEFI/BOOT/BOOTRISCV64.EFI(the UEFI removable-media path; a displaced loader is saved once as.bak).mrbml-install(8)has the explicit--root-label/--prefixforms. - On your boot/root filesystem, create
/boot/qsoe/and copy the kernels there:modpkg.cpio, which both variants boot, and your board'sskimmer-<board>kernel for QSOE/N andsel4-<board>.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)' {
multiboot3 /boot/qsoe/sel4-sifive.elf mainfs=/dev/nvme0n1p8
module3 /boot/qsoe/modpkg.cpio modpkg
}
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. Chapter 2 of the
User Guide covers each board.
Building from source
QSOE is built with a riscv64-linux-gnu- cross toolchain (rv64gc) and a stock
make; QEMU is handy for testing. The package manager, qupkg, is
written in FreePascal, so the build also wants fpc; QSOE/L's adds seL4's
tools (cmake, ninja, dtc and a few Python
modules). make checks for all of them first and names what is missing. 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 nvme # the disk image, its system volume an installed qsoe-base 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 on each board, the shell, the basic commands, the text editor and the utilities, sound, and packages.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. 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 — with a chapter for each release since 0.3, and an appendix that compiles SQLite against QSOE and lists exactly what it finds missing.
Roadmap
It is often said that the Linux kernel has no roadmap. QSOE does — the releases that carry it from today's 0.4 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. (released September 2026 — release notes)0.3— Writable filesystem.qrvfswrites: create, unlink, truncate, rename, symbolic links; checked byfscheckbefore every mount and proven by a stress that fills the disk and reads every byte back. With it: taskman as the loader sharing one copy of a library's text, identity that reaches every server, the VisionFive 2, and QSOE/L on every hart. A disk that is only read can afford to be approximate; a disk that is compiled on cannot — and 0.6 compiles on it. (released September 2026 — release notes)0.4— Sound out. Audio on every board and both kernels — HDMI, DisplayPort and the VisionFive 2's jack — with a player for WAV and Ogg Vorbis, clean beside the full test suite. 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. With it: the base system as a package, thequpkgpackage manager, and a C compiler that runs on QSOE. (current — release notes)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.