╔══════════════════════════════════════╗ ║ M I N E R V A O S ║ ╚══════════════════════════════════════╝
| MANUAL | DOWNLOAD |
| Architecture | x86-64 Long Mode (AMD64), Ring 0 only, kernel + userspace |
| Video | VESA Linear Framebuffer — 1280x720x32bpp (preferred), 1024x768x32bpp, 800x600x32bpp fallbacks |
| Storage | MinervaFS — Log-Structured Copy-on-Write, 4KB blocks, 2048 inodes, CoW checkpoints, snapshots |
| Network | NE2000 ISA — Ethernet/ARP/IPv4/ICMP/UDP/TCP + Tuple Space (Ethertype 0x88B5) |
| Init | Gracie Lisp Interpreter — no systemd, no init, no PID 1 |
| IPC | Linda Tuple Space — 1024 slots, pattern matching, TTL expiry, network-transparent broadcast |
| GUI | MinervaWM — 12 windows max, compositing, Z-order, 4 themes, dirty-rect tracking, star menu |
| Scheduling | Cooperative fibers — 64 tasks, 3 priorities, 3 rooms, Sandman watchdog (8253 PIT 100Hz) |
| Audio | Sound Blaster 16 — DSP + OPL3 FM synthesis, DMA streaming, 8/16-bit PCM |
| Input | PS/2 Keyboard (Set 1 + US/TR-Q layouts) + PS/2 Mouse (IntelliMouse wheel) + USB UHCI HID |
| Memory | PMM bitmap 16GB, VMM 4-level page tables, 64MB kernel heap, PAT write-combining |
| Media | WAV audio (SB16 DMA), AVI video (JPEG/MJPEG + Huffman IDCT), PNG decode (DEFLATE + Adam7) |
| Toolchain | i686-elf-gcc, NASM, GNU ld — freestanding, no libc, no standard library |
| Image | os.img: 2MB (boot + kernel), disk.img: 256MB MinervaFS (apps + media + ROMs) |
Stage 1 — MBR (boot/boot1.asm, 512 bytes)
Loaded by BIOS at 0x7C00. Supports both CHS and LBA disk access (DAP structure at 0x500). Reads up to 1024 sectors (512KB) from disk to 0x1000:0x0000 (physical 0x10000). Detects VBE framebuffer info (stored at 0x9000) and mode info (0x9100). Verifies long mode support via CPUID 0x80000001 (bit 29 of EDX). Enables A20 gate through BIOS function, then fast A20 via port 0x92 as fallback. Gathers E820 memory map at 0x8000 (128 entries, 24 bytes each). Configures a minimal GDT (null + kernel code 0x9A + kernel data 0x92, granularity 0xCF). Enables Protected Mode (CR0 bit 1) and far-jumps to 0x1000:0x0000.
Stage 2 — Loader (boot/boot2.asm)
Builds a temporary page table at 0x1000 for identity mapping of the first 4MB plus a higher-half mapping at 0xFFFFFFFF80000000. Enables PAE (CR4 bit 5), loads PML4 into CR3. Activates long mode via EFER MSR 0xC0000080 (bit 8), then enables paging (CR0 bit 31). Far-jumps to the 64-bit kernel entry at 0xFFFFFFFF80001000. Passes a MinervaBootInfo struct through RDI containing: framebuffer physical address, width, height, bits-per-pixel, E820 map pointer, RSDP pointer, and ramdisk info.
Kernel Entry (boot/kernel_entry.s)
64-bit ELF object linked with the kernel. Clears the BSS section (rep stosb, _sbss to _ebss). Sets stack pointer to 0x80000. Calls kmain(boot_info) with the boot info pointer from RDI. Halts on return.
kmain() executes the following subsystem initializations in strict order:
Serial & Debug: serial_init (COM1 0x3F8, 38400 baud) → klog (kernel logging)
CPU Tables: gdt_init (5 entries) → idt_init (256 entries, PIC master→0x20, slave→0x28, PIT divisor 11932≈100Hz)
Memory: pmm_init (E820 bitmap, 16GB max) → vmm_init (4-level page tables, PAT MSR 0x277 write-combining)
Storage: ata_init (primary 0x1F0) → ahci_init (PCI class 0x01/0x06/0x01)
System: acpi_init (RSDP scan 0xE0000–0xFFFFF) → pci_enumerate (bus 0–255, slots 0–31, funcs 0–7 via 0xCF8/0xCFC)
Input: keyboard_init (IRQ1, Set 1 scancodes) → mouse_init (IRQ12, IntelliMouse detection 200→100→80)
Hardware: serial_int_handler_enable → rtc_init (CMOS 0x70/0x71) → speaker_init (PIT channel 2) → audio_init (SB16 DSP 0x226, IRQ5)
Filesystem: fs_init (MinervaFS mount from ATA primary)
Services: wm_init → tuple_space_init (1024 slots) → gracie_init → mod_init_all (.lisp scan) → desktop_init
Scheduler: scheduler_init → sched_loop (never returns)
PMM: Bitmap allocator, 1 bit per 4KB page frame. PMM_BITMAP_SIZE = 512KB (16GB / 4096 / 8). pmm_alloc_block() scans bitmap for first free bit. pmm_alloc_dma() allocates from first 16MB for legacy DMA (SB16, NE2000). pmm_free_block() clears bit. Tracks total/free blocks in kstat.
VMM: x86-64 4-level page tables (PML4→PDPT→PD→PT). Page index macros: PML4_INDEX(x)=(x>>39)&0x1FF, PDPT_INDEX(x)=(x>>30)&0x1FF, PD_INDEX(x)=(x>>21)&0x1FF, PT_INDEX(x)=(x>>12)&0x1FF. Page flags: PRESENT=0x01, RW=0x02, USER=0x04, PWT=0x08, PCD=0x10, LARGE=0x80, PAT_LARGE=0x1000, DEMAND=0x100. KERNEL_VMA = 0xFFFFFFFF80000000. PAT MSR 0x277 sets Write-Combining for framebuffer. vmm_map_page() does 4-level walk, allocates intermediate tables from PMM. vmm_pagefault() handles demand paging + protection violations.
Heap: 64MB static array. malloc_header: size + free flag + canary (0xC0DEBABE) + reserved. free() marks block free + coalesces adjacent. kcanary_verify() walks entire heap every 10 ticks. Tail canary 0xDEAD1337. Full libc: memset, memcpy, memcmp, strlen, strcmp, strstr, strcpy, strcat, strncpy, strdup, snprintf, vsnprintf, strtol, atoi, itoa, UTF-8 decode/encode. PRNG: krand()/ksrand().
No preemption, no ring transition, no TSS swap, no INT 0x80. All tasks run as cooperative fibers in Ring 0. SCHED_MAX_TASKS = 64. Task struct: id, name[28], type (KERNEL=0, SERVICE=1, APP=2), state (DEAD=0, ALIVE=1, SLEEPING=2, WAITING=3), priority (IDLE=0, NORMAL=1, HIGH=2), room (TEAROOM=0, KITCHEN=1, GARDEN=2), callback functions (tick_fn, key_fn, mouse_fn, msg_fn), sleep_until, total_ticks, pagedir, watchdog, MXE entry/API pointers, fiber support, canary. Each task owns a private 4KB stack. macs_yield() stores RSP+RIP into TCB, calls asm_switch() which xchg-swaps RSP. macs_spawn() creates fiber with 16KB stack + canary protection. Scheduler scans linearly per priority: HIGH round-robin, then NORMAL, then IDLE.
Based on David Gelernter's Linda coordination language (Yale, 1985). Static pool of 1024 ts_entry slots. Each entry: GracieVal* tuple, TTL in ticks (0 = infinite; decremented each tick; expired reclaimed), occupied flag. Spinlock-based concurrency. Operations: ts_out (non-blocking add), ts_read (non-blocking read-no-remove), ts_in_blocking (blocking read-and-remove, yields CPU). Pattern matching: each element compared literally (integer, string, symbol); wildcards start with ? (e.g. ?x) and bind to result.
Network: Binary wire format — type tag + payload: NUM=4 bytes, SYM/STR/ERR=2-byte length prefix + data, LIST=2-byte count + items. Custom ethertype 0x88B5 for raw Ethernet broadcast. Operations: TUPLE_OP_OUT=0, TUPLE_OP_IN=1, TUPLE_OP_READ=2, TUPLE_OP_DATA=3. UDP port 31415 for datagram mode. net_loop demuxes ARP vs IP; UDP 31415 calls ts_net_receive to deserialize and merge into local pool. Entire LAN becomes single shared tuple space.
After hardware init, gracie_init() boots the interpreter. mod_init_all() scans 0:/ for .lisp files, evaluates in isolated env chains. System init: (desktop-start) (puts "MinervaOS: system ready") (system-loop).
Data types (GracieVal): GR_ERR=0, GR_NUM=1 (int64_t), GR_SYM=2 (interned via hash table), GR_STR=3 (char*+len), GR_LIST=4 (count + cell array), GR_FUNC=5 (lambda: formals + body + env), GR_MACRO=6, GR_QUASIQUOTE=7, GR_UNQUOTE=8, GR_UNQUOTE_SPLICING=9. GracieEnv: parent pointer, count, syms[96], vals[96]. GRACIE_ENV_MAX = 96.
Reader: Recursive-descent S-expression parser. Quote ('), quasiquote (`), unquote (~), unquote-splicing (~@). Line comments (;), block comments (#| ... |#). Escape sequences: \n \t \\ \" \0. Evaluator (gr_eval): if/do/let/fn/fn*/def/def*/and/or/try/throw/eval/quote/quasiquote special forms. Lambdas close over definition env. Environment chaining: child inherits parent.
100+ Builtins: Console (puts, clear, color, con_putchar, con_puts), Filesystem (fs-list, fs-read, fs-write, fs-append, fs-delete, fs-size, fs-free, fs-rename, fs-stat), Math (+ - * / % abs min max rand srand), String (str-len, str-cat, str-sub, str-find, str-replace, str-upper, str-lower, str-trim, str-split, str-reverse), List (list car cdr cons len append nth slice map filter reduce sort reverse), Pairs (pairs assoc keys values), Type (type number? string? list? symbol? function? nil?), Comparison (= != < > <= >=), I/O (read-file write-file load load-mod run-mxe), Network (http-start http-poll http-cancel net-online), Audio (beep sb-play sb-stop sb-vol), System (uptime ticks key mouse reboot halt peek poke), PCI (pci-list), JIT (sys-jit-alloc sys-jit-free sys-jit-exec sys-jit-idct), Desktop (desktop-start system-loop), Regex (re-match re-find re-all), Drawing (draw-rect draw-line draw-circle draw-text fill-rect fill-circle), Kstat (kstat kstat-dump), Tuple Space (ts-out ts-in ts-read ts-in-blocking).
JIT Compiler: lib/jit.c writes raw x86-64 machine code into JitCtx buffer. JitReg enum: all 16 x86-64 registers (RAX-R15). Complete instruction emitter: REX prefix, ModR/M, SIB bytes. Instructions: MOV (r32/m32, r64/m64, r32/imm32, r64/imm64), IMUL, ADD, SUB, XOR, OR, SAR, SHL, PUSH, POP, RET, NOP, CMOVL, CMOVG, MOVSXD. jit_exec() executes with up to 6 arguments (SysV ABI). Used for IDCT (1024-MAC fully unrolled, ~17KB generated code) and YCbCr conversion in videoplayer.mxe. Built-ins: sys-jit-alloc, sys-jit-exec, sys-jit-free, sys-jit-idct.
Gtrace (GracieTrace): Inspired by DTrace. Hijacks MxeAPI function pointers at runtime — replaces C pointers in g_api table with Lisp lambdas. Enables live instrumentation of kmalloc, fs_read, fb_pixel calls without breakpoints or INT 3.
Module System: GmMod linked list (name, env, next). Loads .gm files from filesystem. Each module gets own GracieEnv. mod_init() / mod_load() / mod_unload() for dynamic management.
Magic: 0x4D494E52 ("MINR"). Block size: 4096. Max nodes: 2048. Superblock at MINERVA_FS_START_LBA = 2048 (offset 1MB). Checkpoint, snapshot, freed-block tracking, CRC32 integrity. Path separator: : (colon, not /). LRU cache: 16 slots. Snapshots: 8 max, tag + checkpoint. fs_init() reads superblock, validates magic/version. fs_new() allocates inode. fs_rd()/fs_wr()/fs_append_file() for file I/O. fs_find() path resolution. fs_list()/fs_list_top() directory listing via callbacks. fs_free() free space calculation. fs_sync() writes superblock to disk. fs_start_read()/fs_poll() async disk I/O. CoW: dirty writes > 32 triggers checkpoint to new LBA. Superblock backup at offset 512 for power-loss recovery. freed pool: 1024 entries with coalescing + best-fit allocation.
| DRIVER | PORTS / BASE | IRQ | DETAILS |
| Framebuffer | VBE linear FB from BootInfo | — | Double-buffered, 32x32 dirty-rect grid, Bresenham line, alpha blend, sprite blit (key 0xFF00FF), 8x16 bitmap font, 3 cursor types |
| PS/2 Keyboard | 0x60 (data), 0x64 (cmd) | IRQ1 | Set 1 scancodes, US + TR-Q layouts, 64-entry ring buffer, 3-tick debounce, key_state[512] press map, 280+ key constants |
| PS/2 Mouse | 0x60 (data), 0x64 (cmd) | IRQ12 | IntelliMouse detection (200→100→80), 3/4-byte packets, left/right/middle buttons, wheel, relative deltas |
| ATA PIO | 0x1F0-0x1F7, 0x3F6 | IRQ14 | Primary channel only, state machine (IDLE→WAIT_READY→SEND_CMD→WAIT_DRQ→XFER→FLUSH→DONE), sync + async I/O, 28-bit LBA |
| AHCI SATA | PCI ABAR mapped | PCI | HBA_MEM struct, 32 command slots, 8 PRDT entries/slot, COMRESET port detection, DMA read/write, signatures SATA=0x00000101, ATAPI=0xEB140101 |
| Sound Blaster 16 | 0x226 (reset), 0x22A (read), 0x22C (write), 0x22E (ack), 0x224/0x225 (mixer) | IRQ5 | DSP reset + version check (expect 3.x), DMA1 ch1/3 (8-bit), DMA2 ch5/6/7 (16-bit), 64KB buffer, OPL3 FM 0x388/0x389, 5000-44100Hz, 18-channel 2-op FM, volume control |
| NE2000 NIC | 0x300-0x31F | IRQ12 | RX ring 0x46-0x80 (128 pages), TX page 0x40, MAC from PROM, Ethernet/ARP/IPv4/ICMP/UDP/TCP stack, static IP 10.0.2.15, gateway 10.0.2.2, ARP cache 16 entries, HTTP client, custom ethertype 0x88B5 |
| PCI | 0xCF8 (addr), 0xCFC (data) | — | Bus 0-255, slots 0-31, funcs 0-7, max 256 devices, PciDevice struct (12 fields), BAR parsing, busmaster enable, vendor IDs: Intel 0x8086, Realtek 0x10EC, AMD 0x1022, Nvidia 0x10DE |
| ACPI | RSDP 0xE0000-0xFFFFF | SCI | RSDP scan, RSDT/XSDT walk, FADT parse (PM1a_CNT_BLK, PM1a_EVT_BLK, reset_reg), acpi_poweroff via FADT reset port |
| Serial | 0x3F8 (COM1) | IRQ4 | 38400 baud (divisor 3), 8N1, polled TX/RX, IRQ4 receive, ser_readln() line-buffered input, klog/klogf kernel logging |
| RTC | 0x70 (addr), 0x71 (data) | IRQ8 | BCD/binary auto-detect (Reg B bit 2), RtcTime struct (year/month/day/hour/min/sec), update-in-progress wait |
| USB UHCI | PCI BAR mapped | PCI | PCI class 0x0C/0x03/0x00, frame list 1024 entries, TD (UHCITD) + QH (UHCIQH), HID boot protocol keyboard, 8-byte input reports, TD_ACTIVE=1<<23, TD_ERROR=1<<22 |
| PC Speaker | PIT channel 2 | — | Direct PIT frequency generation, boot_chime() startup melody, PCM via SB16 DMA callback with fsin_approx() sine lookup |
Magic: 0x4D5845 ("MXE"). FlatHeader: magic(4B), version(1B), bits(1B), flags(2B), entry(4B), code_size(4B), data_size(4B), bss_size(4B), reloc_count(4B). Load base: 0x100000000 (4GB virtual). Heap base: 0x200000000 (8GB). Max size: 4MB. Compiled with -mcmodel=large, linked via mxe_linker.ld. Loader (kernel/mxe.c) reads from MinervaFS, validates magic, allocates RWX page, copies code/data, zeros BSS, applies base relocations. Creates VMM address space (fresh PML4), sets up stack, passes RDI = pointer to MxeAPI struct (~200 C function pointers), calls entry. MXE color constants: MXE_COL_BLACK=0 through MXE_COL_WHITE=15. Key constants: MXE_KEY_UP=256 through MXE_KEY_F5=284. MxeMsg: type, from, seq, size, data[60].
MxeAPI categories (~200 pointers): Framebuffer (pixel/rect/char/putstr/line/circle/blit/flip), Window Manager (create/destroy/move/resize/draw/title/shadow/drag), Scheduler (spawn/yield/sleep/focus/send/recv), Tuple Space (out/in/read/eval), Gracie (eval string), Kernel (malloc/free/memset/memcpy/strcmp/strlen/snprintf), Filesystem (open/read/write/close/delete/rename/stat/list/free/append), Kstat (create/get/set/dump/list), Huffman (compress/decompress), Keyboard (read/peek/state/modifiers), Mouse (read/position/buttons), Events (wait/poll), Speaker (beep/beep_off), RTC (read_time), SB16 (play/stop/volume/FM), Streaming (start/stop/refill), Delay (ms/uptime), Random (rand/srand), PCI (list/read_config/busmaster), Network (http_start/http_poll/http_cancel/udp_send/arp_resolve/get_ip/get_mac), ATA (read), PNG (decode), JIT (alloc/free/exec/idct_size/idct_fill).
WM_MAX = 12 windows. WM_TITLE_H = 22px. WM_BORDER = 2px. WM_TASKBAR_H = 26px. WmTheme: name[16], colors[16] (TITLE_BG_TOP/BOT, WIN_BG, BORDER, BTN_CLOSE/HOVER, TITLE_TEXT, BTN_MIN, TASKBAR, TASKBAR_TEXT, TASK_ACTIVE, ACCENT, SHADOW, BTN_MIN_HOVER), corner_radius, border_w, title_gradient, shadow_size. 4 built-in themes: default (purple), pastel, ocean, retro. Doubly-linked Z-ordered window list. Title bar: active=blue, inactive=gray, close button hit-test. Desktop at Z=0. Focus via focused_window; raise/focus moves to front. wm_composite() renders all windows with shadows + borders. Dirty-rect tracking via wm_mark_dirty_all()/wm_mark_dirty_rect(). Cursor compositing via wm_swap_with_cursor(). Clipboard: copy/paste via global buffer. Boot splash: animated "MINERVA" text with letter-by-letter animation, stutter effect (8 positions), trail effect (5 ghosts), "OS" subtitle at scale 3, gradient line, progress bar with marquee (3 sliding boxes). Panel: bottom taskbar, task buttons per window, RTC clock HH:MM, volume icon, power button. Star Menu: 24 constellation positions, 39 constellation edges, 24 pastel star colors, alpha fade animation, keyboard navigation (arrow keys), mouse hitbox detection. Desktop wallpaper: purple gradient + scattered stars. Screensavers: Off, Starfield, Matrix, Bounce, Snow.
| APP | DESCRIPTION |
| shell.mxe | 48x20 char grid, 128-char input buffer, green-on-dark theme (output 0x55FF78, prompt 0x00D278), blinking cursor (20-tick cycle), evaluates via K->gr_eval() |
| editor.mxe | 256 lines x 160 cols, 44px line numbers, file I/O via MXE API, Ctrl+S/O/Q, cursor blink (24-tick cycle), status bar with filename/line/col/modified |
| filemgr.mxe | Dual-pane directory browser, file type icons (MXE/WAV/AVI/CH8/MD/GM), zone navigation with "..", copy/rename/delete operations, size formatting B/K/M |
| calc.mxe | 4x5 button grid (56x40 buttons), operations + - * / % +/- backspace, 2x scale for short numbers, keyboard shortcuts for digits/operators/Enter/C |
| paint.mxe | 256x256 canvas, tools: pencil/line/rect/circle/eraser/fill(color picker), 24-color palette, 32-level undo buffer, zoom 1-8x, Bresenham line, midpoint circle, scanline flood fill, .mimg save/load |
| browser.mxe | HTML parser with DOM tree, 8 tabs, HTTP client via MXE network API, CSS color parsing (hex/named), link rendering, URL input, bookmark bar, chunked transfer download, scroll |
| taskmgr.mxe | Window list with title + status (ACTIVE/idle), kill (K), refresh (R), uptime HH:MM:SS, task count, focused window |
| player.mxe | FM synthesis via SB16/OPL3, built-in songs (Tetris/Star Wars/Mario), 16 FM patches, WAV streaming, spectrum visualizer 60 bars, volume/bass/treble, playlist 32 tracks, 32KB stream buffer |
| videoplayer.mxe | AVI container (RIFF), JPEG/MJPEG decode with Huffman tables, WAV audio sync, frame index from idx1 chunk, seek, AVI_RAW_LBA=260000 direct disk access, JIT IDCT for decoding |
| settings.mxe | 3 tabs (Appearance/Widgets/System), 10 themes (Ocean/Sunset/Forest/Candy/Midnight/Retro/Lavender/Mint/Coral/Amber), screensavers (Off/Starfield/Matrix/Bounce/Snow), clock widget (4 styles), calendar (Zeller's congruence) |
| clock.mxe | CMOS RTC read (0x70/0x71), analog + digital display, sin/cos lookup tables (60 entries for clock hands) |
| ide.mxe | 300-line editor buffer, 160 cols, 300-line REPL with 64-entry history, live auto-evaluation, tab completion from 50+ builtins, split view (editor top, REPL bottom), dark theme bg=(20,22,30) |
| viewer.mxe | Gallery scans filesystem for .png and paint_save* files, PNG decode via MXE API, pan/scroll drag, zoom scroll wheel, file list browser |
| tetris.mxe | 10x20 board, 16px cells, 7 tetrominoes (I/J/L/O/S/T/Z as 16-bit bitmaps), ghost piece, hold piece, xorshift PRNG (state=1337), line clear flash |
| snake.mxe | 20x20 grid, 16px cells, wrapping walls, food pulsing animation, directional eyes, score/length/speed display, pause |
| wolf3d.mxe | 32x32 map, 8 wall types, raycasting FOV 64 deg, 700 steps/ray, fish-eye correction via cosine, distance fog, fiber-based rendering, 256-entry sin/cos LUT |
| chip8.mxe | 4KB memory, 16 registers V0-VF, 16-level stack, 64x32 display at 8x scale, ROM scanner (.ch8 files), IBM logo built-in, full opcode decoding, delay/sound timers |
| teapot.mxe | 3644 vertices, flat-shaded triangles, Z-buffer rendering, mouse drag rotation, scroll zoom |
| 3d-demo.mxe | Trefoil knot (768 vertices) + Mobius strip (493 vertices), Z-buffer (uint16_t/pixel), flat shading, face normal calculation, mouse drag rotation, scroll zoom, integer sqrt for normals |
| 3d-wireframe.mxe | 9 models: cube/pyramid/octahedron/gem/icosahedron/dodecahedron/sphere/torus/cylinder, wireframe rendering, auto-rotation, keyboard rotation, zoom 256-2048 |
| FILE | SIZE | CONTENTS |
| hdd.img | 258 MB | Bootable — os.img + disk.img combined. All apps, kernel, media, modules. |
| os.img | 2 MB | MBR boot1 + boot2 + kernel (all drivers, gracie, gui, lib, fs) |
| disk.img | 256 MB | MinervaFS — 24 MXE apps, 3 CHIP-8 ROMs, 2 Lisp modules, media files |