OPERATING SYSTEMS · SMALL ENOUGH TO READ · HONEST ENOUGH TO PROVE

NANOKERNEL.ORG

We build nanokernels — operating systems so small that every byte can be named, audited, and booted in front of you. Projects here ship as bytes + proof, never as promise.

PROJECTS

NK-001 · NANOKERNEL · x86-32

BasmOS

A complete operating system in one 512-byte boot sector: protected mode, paging, preemptive scheduling, two tasks, IPC. Its sibling sector adds a real ring-3 monitor, TSS and user-module loader. No second stage; assembled 100% with BASM.

512 B sector401 B payload232 B machine-contract256 B JASH/CPL3source-built tools QEMU · browser · KVMboots in your browser
ENTER THE SECTOR →
NK-002 · the next nanokernel is being assembled…

DOCUMENTATION

ETHOS

PROOF, NOT PROMISE

Every claim on this site is backed by a byte you can read or a test you can run. If it cannot be verified, it is not written.

EVERY BYTE EARNS ITS SEAT

No runtime code where assembled data will do. No dword where a byte will do. Size is not a stunt — it is a design discipline.

THE ARTIFACT IS THE ARGUMENT

Each project ships inside its own page: the binary, the map of every byte, and an executor to run it. The website weighs more than the software.

A NANOKERNEL · ONE SECTOR · ONE BINARY

512BYTES

BasmOS is a nanokernel: a complete x86-32 operating system — boot, protected mode, paging, preemptive scheduling, two tasks and IPC — living in a single boot sector. No second stage. No bootloader. Assembled 100% with BASM.

401PAYLOAD (B)
317CODE (B)
84DATA (B)
109HEADROOM (B)
0SECOND STAGES
256IPC RING (B)
GITHUB / SOURCE ↗

the entire binary is embedded in this page.

THE PROOF, NOT THE PROMISE

what QEMU verification reads back from VGA memory after boot — and what the emulator below paints live:

3
6
9
_
0xB8000
task0
0xB8002
task1
0xB8004
IPC ✓

the green 9 is task1 printing a byte it received from task0 through the ring — scheduler + trap services + IPC alive in the same 512-byte image.


      
cold. press BOOT.

ANATOMY — 512 BYTES, EACH ONE NAMED

this is not an illustration: these are the actual bytes of basmos.bin, colored by symbol. Hover, focus or tap any byte.

THE ENGINEERING — EVERY BYTE EARNS ITS SEAT

no runtime setup code where assembled data will do; no dword where a byte will do.

11 B

A BOUNDED WORLD SWITCH

xchg esp,[es:other_sp] atomically swaps stacks. popad · mov ds,bp · iretd restores the integer frame and the incoming task's private data selector.

35

ESP BUILDS THE IDT

The stack pointer writes 35 gates backwards with push: every CPU exception is valid, then timer, send and receive. Faults stop instead of triple-faulting.

44 B

A STACK WITH NO ADDRESS

task1's boot frame ships as data inside the sector. Its stack lives right there, cycling over 44 bytes of init code that never runs again. The sector is the kernel, the boot record and the stack.

4 MB

PAGING IN ONE STORE

One PSE directory entry identity-maps 4 MB: mov dword [eax],0x83. The whole machine, one write.

256

STATE INSIDE THE TASK

Each endpoint's cursor lives in its saved ECX. inc cl wraps across the 256-byte ring, and the opposite saved ECX detects full or empty.

1 B

PROTECTED MODE IN ONE BYTE

In real mode, PE is 0 by definition — so inc ax is or eax,1. One byte flips the CPU into 1985's future.

32

TIMER AND YIELD, ONE GATE

IRQ0 and int 32 share one handler. PIC is remapped away from double fault; a software yield's EOI is harmless with an empty ISR.

TASK0 NEVER SLEEPS

The producer's loop holds no hlt and no yield — it is CPU-bound. The white 6 and green 9 can only exist because IRQ0 interrupted a task mid-computation: asynchronous preemption, the strongest claim a timer-scheduled artifact can make.

THE SECTOR LEARNED PRIVILEGE — RING 3 IN 512 BYTES

basmos-sh.bin is the sibling artifact: the record sector stays byte-for-byte intact while a second sector spends its headroom on a real user/kernel boundary.

498 B

KERNEL + USERLAND

Boot, PM32, paging, a 129-gate IDT, PIC/PIT, TSS, COM1 driver, syscall ABI, ring-3 monitor and module loader occupy 498 payload bytes. Twelve bytes remain before 55 aa.

CPL3

NOT PRIVILEGE THEATER

Monitor CS 0x1B covers exactly its 100 bytes. DS/SS 0x23 covers only a 4 KiB arena. Module CS 0x2B executes at most 256 received bytes. TSS SS0:ESP0 owns every return to ring 0; IOPL=0 blocks hardware.

0x80

ONE TRAP LINE

putc, getc, exec and q cross one DPL3 trap gate. The monitor protocol is ? state, r length+bytes, x execute. A module can grow the shell without growing the kernel.

#GP

THE SANDBOX BITES

The verifier loads three hostile modules. cli, out dx,al and loading kernel DS all stop in the exception gate with saved CS=0x2B. No triple fault, no accidental privilege.

IRQ0

A DOT IS A WORLD TRIP

Every timer interrupt emits .. Seeing the protocol continue to Z> proves CPL3 → TSS stack → ring 0 → CPL3, then module output and q back to the monitor.

×2

INDEPENDENT PROOF

QEMU reads IDT, TSS and PDE0 through QMP. bemu-nano inspects saved user selectors in KVM. Both receive the same binary module and require load, execute and return.

$ make shell
>?3rxZ>
RESULT: PASS — 512B ring-3 monitor loaded, ran and returned from a user module

$ make verify-shell  # QEMU + KVM + three hostile CPL3 modules

JASH — THE SHELL THAT KNOWS WHAT IT KNOWS

The current artifact is a 255-byte IA-32 nucleus plus one reserved byte, executing at CPL3 with a 3,584-byte data Pack. It offers 14 exact commands and labels shipped facts separately from the runtime CPUID vendor measurement.

255+1

A COMPLETE NATIVE NUCLEUS

255 native bytes implement Pack loading, CPUID vendor measurement, line editing, exact table dispatch, output, Deck selection and the int 0x80 console boundary. One byte is reserved; CS limits execution to the 256-byte nucleus.

3584 B

PRESENTATION LIVES OUTSIDE CS

The J-Pack at DS:0x200 carries text, a 15-cell dispatch vocabulary and EVM1/SFC1/DCK1/SIG1 manifests. It is outside module CS and is not fetched as code, but it remains writable through the arena DS; this is not an immutable or hardware-NX claim.

SFC1

TYPED SURFACES, NOT TTY

The six descriptive Surface entries publish wire0:Duplex<Byte>, glyph0:TextOverWire, arena and code views, convention-stable facts and a kernel outside user segments. The facts storage is physically writable, as the live transcript states.

DCK1

DECKS ARE LIVE COMPOSITIONS

jack toggles one real UI composition bit. In lab, map selects a masked response; in zero, it selects the visible map. The bytes and hardware permissions do not change, so this is view composition, not authority attenuation.

14

EXACT COMMANDS

map, help, uname -a, sigil, layout, surfaces, decks, attest, palette, anatomy, clear, limits, jack and bye. There are no aliases or canned counterfactual commands.

SIG1

ARTIFACT-BOUND SIGIL

NK-SIGIL/1 encodes the first 16 bytes of SHA256(basmos-sh.bin || jash.bin); each braille dot represents one bit. The full root is 123d1b5b871ace1549494355dba65267a28d1ba53d6fa860e42f317c894f3da0.

Verified real KVM and CPL3 JASH transcript showing NK-SIGIL/1, attest, map, jack, surfaces, anatomy and bye
Verified real KVM transcript rendered from website/jash-live.svg. Read the plain transcript, session manifest, and artifact manifest.
$ make jash-live  # open the real native C/KVM Wire session

Current identities: prompt jash@nanokernel.org · nucleus SHA-256 3ed12f5d1d90d006522fab676e796441fb870e8b23083dfd6d1907f8693b536d · Pack SHA-256 97789cb32d65251f9f748bd4efbb4e3c6a8c2a0aff6bc71abd31a9d72d61f3f0. PRF1 lines are evidence records checked externally, not cryptographic signatures.

BOOT WITHOUT BOOT — THE 232-BYTE MACHINE

the same basmos.basm source assembles into two personalities. The second one never boots at all.

232 B

ZERO BYTES OF BOOT

basm -DBEMU_CONTRACT drops the real-mode prologue, embedded GDT, paging setup, PIC and PIT. The 232-byte contract guest is 169 bytes smaller than the 401-byte payload and 280 bytes smaller than the complete 512-byte sector. What remains is IDT, task domains, scheduler, IPC and tasks; bemu-nano starts the vCPU directly in protected mode with paging on.

0

PORTS TOUCHED

Under the contract the guest speaks to no device at all — measured PIO writes: zero. There is no PIC and no PIT. Time is one instruction: hlt asks the machine for the next tick, and the VMM injects vector 0x20. The guest defines its own physics.

KVM

AUDITABLE HOST RUNNER

bemu/bemu_nano.c uses /dev/kvm, 4 MB of guest RAM, one vCPU and minimal timer/UART handling. It loads the image at 0x7C00 without firmware, BIOS or ELF. An HLT with IF=0 — the guest's fail-stop exception gate — is reported as CRASH, never revived.

2

CONTRACTS, ONE VMM

bemu-nano basmos.bin behaves like a BIOS that already read the disk (real mode, 0xAA55 checked). bemu-nano basmos-vm.bin --contract writes the GDT and the page directory as machine physics and enters at PM32+PG. Same run loop, same fail-stop symmetry, same PASS criteria.

DETERMINISM — THREE EXECUTORS, ONE TRUTH

the same 512 bytes are exercised by three independently implemented execution paths. Their specified observables must agree or verification fails.

QEMU

REAL EMULATED SILICON

make verify-qemu boots the sector, dwells 2 s, then reads physical VGA through the QMP monitor: 33 0f 36 0f 39 0a. task0 never sleeps, and a heartbeat byte at 0x6FC must keep incrementing — the green 9 and the living heartbeat are impossible without asynchronous IRQ0 preemption.

JS

THE INTERPRETER IN THIS PAGE

The emulator below runs the actual shipped bytes embedded in this HTML and stops at exactly 2,000,000 instructions: 44 timer IRQs, 0 yields, 126,144 sends, 22 receives and heartbeat 44. It models only the instruction, segmentation and timer behavior needed by this artifact; it does not model paging, the PIC or the PIT. Press BOOT.

KVM

BARE-HYPERVISOR EXECUTION

make verify-bemu runs both personalities through Linux KVM: 64 ticks, 32 of which preempt the CPU-bound producer mid-loop (the VMM is the 18.2 Hz PIT), with pio-outs=0 on the 232-byte contract build.

C

EXECUTABLE SACRED GEOMETRY

basm_sacred.c is a generated Metatron's Cube translation unit around the readable assembler. CI compiles both with warnings as errors and requires all five guest artifacts to remain byte-identical.

this is the disruptiveness nobody is selling: not “trust the hardware vendor's attestation”, but an implementation small enough to inspect directly — 512 bytes of guest plus a purpose-built VMM and assembler whose complete source is in this repository — checked across diverse execution engines.

MEMORY MAP — EVERYTHING BELOW 1 MB

a single 4 MB PSE entry covers this kernel's entire universe.

rangesizeuse
0x00500–0x00617280 BIDT, 35 gates
0x006FC1 Btimer heartbeat
0x00700–0x007FF256 BSPSC IPC ring
0x00800–0x008FF256 Btask0 DS window
0x00900–0x009FF256 Btask1 DS window
0x00FD4–0x00FFF44 Btask0 saved registers and interrupt frame; stack grows down from 0x1000
0x01000–0x01FFF4 KiBpage directory; PDE0 at 0x1000
0x07C00–0x07DFF512 Bkernel and boot-sector image
0x07C8F–0x07CBA44 Btask1 recycled register/interrupt frame and stack, overlapping dead initialization bytes in the image
0xB8000–0xB8F9F4,000 BVGA text memory

task1 has no separate stack allocation: other_sp = t1frame−32 = 0x7C91. Its 32-byte saved-register frame and 12-byte interrupt frame cycle through 0x7C91–0x7CBC.

SCALE (LOGARITHMIC — IT'S THE ONLY WAY)

NanoOS 2.1 (2004) is the same size with preemption and IPC in real mode. pczero is a PM32 scheduler neighbor; its reproduced functional image is 18,060 bytes and the reviewed code has no paging or IPC. Sizes are comparison references.

THE RECORD — A DATED SURVEY RESULT

the public prior-art survey covered GitHub, the web, academic literature and the demoscene. Full evidence table and limitations: RESEARCH.md.

512 B

THE CLAIM (BARE METAL)

In the public survey completed on 2026-08-19, BasmOS is the smallest publicly verifiable IA-32 nanokernel found in the category requiring protected mode, active paging, IDT and timer, at least two timer-preempted tasks and functional IPC. The complete bare-metal artifact is 512 bytes; its payload is 401 bytes.

232 B

THE CLAIM (MACHINE CONTRACT)

Under the bemu-nano contract the same source ships as 232 bytes — always labeled as such, never as bare metal. On bare metal the answer stays 512 B / 401 B, full stop.

150×

RELATED 1992 NANOKERNEL SCALE

The 1992 KeyKOS nanokernel paper describes about 60 KB of executable code. BasmOS implements a compact kernel core — preemption, trap services and logical IPC between shared-CPL0 tasks — in 401 bytes. With the machine contract: 259× smaller.

3

EXECUTORS THAT MUST AGREE

QEMU and the interpreter execute the 512-byte sector; bare KVM (bemu-nano) checks its BIOS personality and the separate 232-byte machine-contract build. Their specified observables must agree or verification fails.

The ranking counts every byte required from BIOS entry to demonstrated behavior; every listed feature is required and additional features are allowed. This is a reproducible dated survey result, not certification by an external record authority.

What we deliberately do NOT claim: “smallest OS ever” without qualifiers — 512-byte real-mode shells and language interpreters exist (bootOS, SectorLISP, SectorForth); they are different classes with no MMU and no concurrency. The claim is the feature intersection, not the sector alone.

RUN IT YOURSELF

Clone the complete source and proof suite, or download the sealed artifacts directly. The installer is reviewed source in this repository; no remote shell pipeline is used.

$ git clone https://github.com/FermiHart/BasmOS.git
 $ cd BasmOS
 $ make toolchain # diagnose compilers, QEMU, NASM, headers and /dev/kvm
 $ make toolchain-install # Debian/Ubuntu: explicit apt installation
 $ make all       # build 512B record + 232B contract + 512B ring-3 sector
 $ make verify-ci # hosted-CI proof path; does not require KVM
 $ make proof     # complete local proof; requires readable/writable /dev/kvm

# Focused execution and verification:
 $ make            # menu of all supported targets
 $ make verify     # QEMU + browser interpreter + bemu-nano (KVM, zero firmware)
 $ make verify-shell # QEMU + KVM: TSS, CPL3, IRQ0, module, hostile instructions
 $ make shell      # load a binary module through COM1 and run it in ring 3
 $ make jash-live  # native C/KVM Wire to the real 256-byte CPL3 shell
 $ make verify-jash # QEMU + KVM, manifests, Decks, ANSI, CS and byte readback
 $ make verify-sacred # compile Metatron C source art; require 5/5 byte identity
 $ make clean-room-proof # erase outputs, rebuild, verify, hash
 $ make run        # QEMU with a read-only floppy image and no network
 $ bemu/bemu-nano basmos.bin              # BIOS-contract: real mode @0x7C00
 $ bemu/bemu-nano basmos-vm.bin --contract # boot WITHOUT boot: PM32+paging direct
 $ make map        # per-symbol byte budget (the data behind this page)

# the repository includes its assembler, KVM runner and verification sources.
# use QEMU or KVM for safe reproduction; raw-device write commands are intentionally omitted.

design rationale & verification methodology: technical report NK-TR-001

NANOKERNEL.ORG · TECHNICAL REPORT NK-TR-001 · AUGUST 2026 · CURRENT REVISION

BasmOS: A Complete Protected-Mode Operating System in a Single 512-Byte Boot Sector

F E R M I ∞ H A R T · contact@fermihart.com · Nanokernel.org
License: BSD 3-Clause · Artifact: basmos.bin (512 B, payload 401 B) — embedded in the project page, bootable there.
Abstract. BasmOS is a nanokernel: an operating system whose entire implementation — bootstrap, protected-mode transition, paged memory, preemptive scheduling, system calls and inter-task communication — fits in the one 512-byte sector the PC BIOS loads. The payload is 401 bytes (317 code, 84 data); the rest is padding ahead of the mandatory 0xAA55 signature. The kernel is assembled entirely with BASM and requires no second-stage loader: the kernel is the boot record. Behavior is verified deterministically by reading VGA text memory back from QEMU after boot, by a small x86 interpreter embedded in the project's web page that executes the same shipped bytes, and through Linux KVM. This report documents the design, the size-engineering techniques, and the verification methodology.

1 · Introduction

We use nanokernel for a kernel whose complete implementation fits inside one 512-byte disk sector — the smallest unit a PC BIOS will load and jump to. Under that constraint, "complete" must be earned rather than asserted: BasmOS enters 32-bit protected mode, enables paging, preempts two tasks on the timer interrupt, and passes bytes between them through a ring buffer — all inside the sector that is also its own boot record.

Contributions: (i) a full protected-mode OS in 401 payload bytes; (ii) a set of reusable size-engineering techniques (§4); (iii) a deterministic, externally observable verification method (§6.1); (iv) independently implemented QEMU, browser-interpreter and KVM execution paths with specified observable agreement (§6.2).

2 · Boot and mode transition

Execution starts in real mode at 0x7C00: cli, DS=0, lgdt, then protected mode. Because CR0.PE is architecturally 0 at reset, inc ax implements or eax,1 in a single byte with no carry possible. A far jump into a flat 4 GB code segment completes the transition. The entire real-mode prologue is 22 bytes.

3 · Memory

Paging is enabled with exactly one store: a single PSE page-directory entry (mov dword [eax],0x83, EAX=0x1000) identity-maps the first 4 MB, and the same register value is immediately reused as CR3. Everything the kernel touches — image at 0x7C00, IDT at 0x500, IPC ring at 0x700, private task windows at 0x800/0x900, stack/page directory at 0x1000, and VGA at 0xB8000 — lies below 1 MB, making the A20 line irrelevant by construction.

SS remains flat for interrupt frames. Task DS selectors are limited to 256 bytes; handlers reach kernel state only through flat ES, and GS is limited to the VGA page. Task CS selectors (0x30, 0x38) bound each task's instruction fetch to its own bytes: a five-byte push/push/retf prologue enters task0 through its window, task1's frame ships CS directly, and runaway execution beyond a window raises #GP13 at the fetch.

4 · Concurrency

The scheduler state is one cell, other_sp. The complete switch is xchg esp,[es:other_sp] · popad · mov ds,bp · iretd: 11 bytes, no current-task index and no branch. EBP carries the incoming task's bounded DS selector, and the interrupted task's code selector returns through the iretd frame itself.

task1 is born from a 12-byte frame (EIP, CS, EFLAGS=0x202) assembled as data; its stack has no allocation of its own, cycling within a 44-byte window of initialization bytes that are never needed again. IRQ0 is remapped to vector 32, outside the exception range; int 32 remains the voluntary yield ABI and shares that handler.

5 · IPC

A single-producer/single-consumer byte ring at 0x700 occupies 256 bytes. Its head and tail live in each endpoint's saved ECX; inc cl provides modulo 256 for free. Comparing the opposite saved cursor distinguishes full and empty, yielding 255 usable queued bytes without a count field. System calls: int 32 = yield, int 33 = send(AL), int 34 = recv → AL (0 = empty).

At boot, ESP builds valid gates for exceptions 0–31 and the three services; vector 13 is patched to a distinct fail-stop gate for exact negative testing. The GDT remains assembled data, with its 6-byte descriptor hidden inside its own null slot.

6 · Verification

6.1 External. QEMU boots basmos.bin; a script then reads guest VGA memory and asserts six bytes: '3',0x0F at 0xB8000 (task0 output), '6',0x0F at 0xB8002 (task1 was preemptively scheduled), '9',0x0A at 0xB8004 (task1 printed a received byte). The producer's loop contains no hlt and no yield — it is CPU-bound — so the 6, the 9 and a heartbeat byte at 0x6FC that must keep incrementing require asynchronous IRQ0 preemption of a task that was mid-computation. QEMU must remain running for a further two-second dwell.

6.2 Browser. The project page embeds a deliberately limited x86 interpreter covering the kernel's required instruction and segmentation behavior and executes the same bytes the page displays and distributes. It does not model paging, the PIC or the PIT. Its virtual timer supplies only the deterministic scheduling behavior needed by this artifact. The bounded 2.0×10⁶-instruction run:

metricvalue
timer IRQs delivered44
yields (int 32)0
sends (int 33)126,144
recvs (int 34)22
heartbeat @0x6FC44 (= ticks)
final VGA bytes @0xB800033 0F 36 0F 39 0A

Independent executors reaching the same observable state provide corroborating implementation evidence while retaining different modeling assumptions.

7 · Size accounting

symbolbytesrole
start22real-mode entry, PE enable, far jmp
pm155IDT construction, segments, paging, PIC/PIT, stack
t1frame12task1 bootstrap frame (data)
task0345-byte retf prologue + private-domain producer: send loop, no hlt, no yield
task133private-domain consumer, including HLT loop
exception / #GP / timer18fail-stop entries; IRQ0 + EOI + heartbeat
do_switch11atomic stack and DS-context switch
sys_send23ES-scoped ring write plus full detection
sys_recv21ES-scoped ring read plus empty detection
idtr6IDTR image
gdt62flat kernel, task data domains, VGA and task code-window descriptors
other_sp4all persistent scheduler state
payload401317 code + 84 data
padding + 0xAA55111109 headroom + 2-byte signature

8 · Related magnitude

The broad predecessor is NanoOS 2.1 (2004), a 512-byte real-mode OS with timer-preemptive multitasking and blocking copy IPC, but no PM32 or paging. A close PM32 scheduler neighbor is pczero; its reproduced functional image is 18,060 bytes and the reviewed code has no paging or IPC. No prior artifact was found with the complete BasmOS feature intersection.

9 · Limitations

Scope decisions, not accidents: a single privilege level (ring 0); no interactive input; trusted CPL0 task code (windows contain runaway fetches, not deliberate far transfers); a static two-task set; a 4 MB identity map; PSE-capable IA-32 hardware; and no recovery policy beyond fail-stop for CPU exceptions. The PIC and PIT are initialized, every architectural exception has a valid gate, and 109 payload bytes remain available.

10 · Reproducibility

make toolchain diagnoses the local prerequisites and make toolchain-install installs the reviewed Debian/Ubuntu package set. make lists the build and proof targets; make verify performs the QEMU readback of §6.1; make map prints the per-symbol byte budget behind §7. The full binary is embedded in the project page — downloadable, copyable as hex, and executable in place. BasmOS is released under the BSD 3-Clause license.

Current revision (August 2026). (a) Verification is three-way — a source-available KVM VMM (bemu-nano, this repo) boots the sector on bare hardware virtualization with zero firmware, alongside QEMU and this page's interpreter; (b) the same source assembles a second personality, basmos-vm.bin (232 bytes), which the VMM enters directly in protected mode with paging on — boot without boot; (c) an extended prior-art survey (web, GitHub, academic literature, demoscene — RESEARCH.md) found no prior one-sector x86 artifact combining protected mode, paging, preemptive multitasking and IPC. This is a dated search result, not a certified world record. The 512-byte sector described by this report includes bounded DS domains and exact data/code #GP denial probes; (d) the sibling artifact basmos-sh.bin spends 498 payload bytes on TSS-backed CPL3, a serial monitor, and loading/executing 256-byte user modules, independently verified by QEMU and KVM; (e) JASH is a 255+1-byte native CPL3 shell with a 3,584-byte data Pack outside module CS, 14 exact commands over 15 cells, a four-operation EVM1 manifest, NK-SIGIL/1, PRF1 evidence and a direct C/KVM interactive Wire.

References

[1] Intel® 64 and IA-32 Architectures Software Developer's Manual, Vol. 3A: System Programming Guide — mode transitions, PSE paging, interrupt descriptors.

[2] calint/pczero — github.com/calint/pczero (magnitude reference).

[3] NanoOS 2.1 — board.flatassembler.net/topic.php?t=2164 (2004 predecessor).

[4] BasmOS artifact: basmos.basm / basmos.bin — this site.