In this blog I share my observations, thoughts and experience about computers, linguistics, philosophy and many other things that interest me.

Saturday, April 25, 2026

QRV v0.25: Booting from Real NVMe on Real Hardware

This is the follow-up to the earlier v0.25 post. Everything described there — the sync_hash fix, the DesignWare iATU, the INTx wiring, the mount command — was validated on QEMU. This post is about what happened when the same build ran on real silicon.

The short version: it works.


How QRV Now Boots on the Unmatched

U-Boot loads the QRV kernel binary and modpkg.cpio directly from the Debian ext4 partition (nvme 0:6) on the Samsung NVMe:

=> ext4load nvme 0:6 0x80200000 /boot/qrv/qrv-kernel.bin
397328 bytes read in 0 ms
=> ext4load nvme 0:6 0x90000000 /boot/qrv/modpkg.cpio
4688384 bytes read in 5 ms (894.2 MiB/s)
=> setenv initrd_size ${filesize}
=> booti 0x80200000 0x90000000:${initrd_size} ${fdtaddr}

QRV lives as a guest on its own machine, loading its boot files from the Debian partition's /boot/qrv/ directory. The QRV filesystem itself is on partition 8 — 2 GiB, type GUID 51525611-322e-4017-bae8-e4d9c9d4e979 — a custom GUID registered for QRV, so partition tools can identify it unambiguously.


The Boot Log

Here is the boot session.

Starting kernel ...

===============================================================================

Boot command line: -Dsbi
Board: SiFive HiFive Unmatched A00
Compatible: sifive,hifive-unmatched-a00
+------------------------------------------+
| QRV Operating System Kernel version 0.25 |
+------------------------------------------+
init_clocks
init_raminfo
asinfo: PCI IO  60080000 - 6008ffff
asinfo: PCI MEM 60090000 - 6fffffff
asinfo: PCI MEM 70000000 - 70ffffff
asinfo: PCI MEM 2000000000 - 3fffffffff
init_mmu
  ram_top = 480000000
  identity_map RAM 80000000..480000000
  ...
  prealloc_kernel_l2: filled 239 empty kernel L2 slots
  enable_mmu: Sv39 paging active
init_intrinfo: timer(base=5,n=1) plic(base=32,n=128)
init_cpuinfo: 4 CPUs, rv64imac, 1 MHz
hwinfo: serial sifive,fu740-c000-uart @ 10010000 irq 39
hwinfo: serial sifive,fu740-c000-uart @ 10011000 irq 40
hwinfo: pci sifive,fu740-pcie ecam df0000000/10000000 irq 57 windows 4
hwinfo: pci dw_pcie_msi dbi e00000000/80000000 irq 56
...
[1] kerlink: boot/taskman.qkx: resolved 6114/6114 external symbols (0 unresolved)
[1] kerlink: boot/taskman.qkx: applied 10631/10631 relocations (0 skipped)
[1] kerlink: boot/taskman.qkx: link complete
...
[1] cpu_start_others: hart 2 started
[1] cpu_start_others: hart 3 started
[1] cpu_start_others: hart 4 started

***********************************
* Welcome to QRV Operating System *
***********************************

     pid tid name               prio STATE       Blocked
       1   1 taskman             10r READY
       ...
       2   1 esh                 10r REPLY       1

Starting slogger...
Starting pci-server...

PCI devices:
00:00.0 PCI bridge [0604]: f15e:0000 (rev 00)
01:00.0 PCI bridge [0604]: 1b21:2824 (rev 01)
04:00.0 USB controller [0c03]: 1b21:1142 (rev 00)
06:00.0 NVM controller [0108]: 144d:a80a (rev 00)
07:00.0 VGA compatible controller [0300]: 10de:128b (rev a1)
07:00.1 Multimedia controller [0403]: 10de:0e0f (rev a1)

Probing for NVMe...
devb-nvme: controller at 06:00.0 BAR0 0x60400000
devb-nvme: controller enabled (CSTS.RDY=1)
nvme: controller VID:DID 144d:144d  ctrl-id 6
  Model:    "SAMSUNG MZVL2512HCJQ-00B00"
  Serial:   "S675NF0R487649"
  Firmware: "GXA7301Q"
nvme: ns 1  size=1000215216 LBAs  lba=512 B  capacity=488386 MiB
devb-nvme: interrupts on (IRQ=57 vector=89)
devb-nvme: GPT OK, 8 partition(s)
  p1: LBA 34..2081 (1 MiB)      type=5b193300-...  name=""
  p2: LBA 2082..10273 (4 MiB)   type=2e54b353-...  name=""
  p3: LBA 10274..227361 (106 MiB) type=c12a7328-... name="EFI"
  p4: LBA 227362..235553 (4 MiB) type=ebd0a0a2-...  name="CIDATA"
  p5: LBA 237568..144941055 (70656 MiB) type=516e7cb4-... name="FreeBSD"
  p6: LBA 144941056..857972735 (348160 MiB) type=0fc63daf-... name="Debian"
  p7: LBA 857972736..891527167 (16384 MiB) type=0657fd6d-... name="swap"
  p8: LBA 891527168..895721471 (2048 MiB) type=51525611-... name="QRV"
devb-nvme: ready (9 path(s), first NS 488386 MiB 512 B/LBA)
br--r--r--  1     0     0 512110190592 nvme0n1
br--r--r--  1     0     0   2147483648 nvme0n1p8

Mounting /dev/nvme0n1p8 at /disk2...
fs-qrv: qrvfs v1, 524288 blocks, 4096 inodes
fs-qrv: mounted qrvfs at /disk2 (dev=/dev/nvme0n1p8)
drwxrwxr-x  2     0     0      768 bin

# cd /disk2
# ls
bin
# cd bin
# ls -la
drwxrwxr-x  2     0     0      768 .
drwxr-xr-x  3     0     0      768 ..
-rwxrwxr-x  1     0     0    60144 syscall_testing
# echo "syscall_testing is here, on NVMe!!!"
syscall_testing is here, on NVMe!!!
# ./syscall_testing
=== QRV Syscall Conformance Test Suite ===

[timers]   25 tests ... all PASS
[sync]     23 tests ... all PASS
[printf]   13 tests ... all PASS

=== Results: 61 tests, 61 passed, 0 failed ===
# shutdown
Shutting down...

What This Means

The partition layout tells the full story without commentary: FreeBSD, Debian, swap, and — at the end — QRV. That last entry was created in advance, left empty, and waited.

The syscall_testing binary is not a toy. It tests kernel call semantics: error returns, resource exhaustion, object reuse, the _r variants that must not touch errno. Sixty-one tests, all passing, executed from a QRV filesystem on a Samsung NVMe, on a RISC-V workstation, through a microkernel IPC stack.

This is a system.


What Remains

Versions 0.26 through 1.0 are still ahead: writable filesystem, proper signals in userspace, network stack, and much more. The documentation effort is just beginning — a User Manual, a Programmer's Manual, a Kernel Calls & Taskman Message Reference, and the Porting Story that has been accumulating as LaTeX chapters throughout this sprint.

But the picture that was forming in someone's mind back in 1999, through RadiOS in assembly, through the HEIG-VD sources found during a COVID lockdown, through a restarted project on a father's birthday in February 2026 — that picture is now a running system.

The work continues.

No comments: