This chapter assumes the ESP firmware is installed and the SD card is prepared (see Installing). Plug in USB-C and watch the monitor.
What you see at power-on
- The desktop and a Console window appear almost at once. The ESP32 starts the display server before the eZ80 has loaded anything. If the screen stays black, check the VGA cable and
UART_DIS1(see Troubleshooting). - MOS text appears in the Console window. The MOS banner (
Agon Platform MOS Version 3.0.2 Arthuron the reference board) and anything MOS or the boot stub prints go into the Console window. MOS does not get the full screen. - The resident loads. The stub streams VIOS from the ESP firmware into RAM in about two seconds.
- VIOS starts and prints its startup lines in the Console window, then the banner and the prompt:
boot confirmed A
autorun task 1
VIOS v0.8 / Forth 24 / Agon Light 2
(c) 2026 Alessandro Iob
vios>
The startup lines tell you what was loaded:
| Line | Meaning |
|---|---|
boot confirmed A |
The confirmed boot bundle (slot A or B) of saved modules loaded and passed its health check. |
boot trial confirmed B |
A pending trial bundle loaded, passed, and is now the confirmed one. |
boot candidate rejected: ... |
A trial bundle failed; VIOS fell back to the confirmed bundle. |
boot recovery: built-in kernel, no valid source bundle |
No saved bundle yet. This is normal on a fresh card: you get the plain system. |
boot recovery: <error> |
The SD card could not be read (no card, not FAT32, card error). VIOS runs without storage. |
user startup: /VIOS/USER.FTH |
Your startup file ran (see below). |
user startup failed: <error> |
Your startup file stopped with an error. Boot continues. |
autorun task N |
A word named AUTORUN was found and started as background task N. |
The whole boot takes about 6 to 8 seconds from power-on to a ready system. These were the phases of one measured boot (firmware main-14, times from the first byte on USB):
| Time | Event |
|---|---|
| 1.9 s | ESP firmware running; MOS banner |
| 2.5 s | Boot stub running, link at 1,152,000 baud |
| 4.4 s | Resident image transferred (about 2 s; 0.8.0's 195 KB image takes 2.3 s in 1,042 blocks) |
| 5.1 s | Resident running (HEALTH flag 0) |
| 7.7 s | Modules loaded, health check passed (HEALTH flag 1, BOOT READY) |
Most of the last step is loading the saved modules. Since the boot-module cache was added, a boot whose modules and resident are unchanged spends about 1.2 s there instead of about 2.5 s. To see where your own boot's time went, type BOOT-TIMES at the prompt:
BOOT-TIMES
It prints one line with the milliseconds spent in each step: storage, boot state, modules (with the number of loads, the slowest module, and cache hits and misses), health, finish and total.
If no SD card or no boot stub is found, MOS stays at its prompt. After about 12 seconds the Console window says "VIOS: no boot SD card, or no viosboot on it. Insert the VIOS SD card and reset the board."
The console
The vios> prompt in the Console window is the Forth REPL. Type a line and press Enter:
2 3 + .
: SQUARE DUP * ;
7 SQUARE .
The line is edited locally on the ESP until you press Enter: Left/Right, Home/End, Backspace, Delete, Esc to clear, and Up/Down for the last four lines. Only then does the whole line go to the eZ80. F1 switches between the console and the workbench editor. Ctrl+Alt+F1 switches between the GUI desktop and a full-screen text console. See The Console and REPL and The GUI.
What you type on the Agon keyboard and what the Mac sends share the same REPL, and host commands appear in the console as ordinary lines. You can watch a script or an LLM work.
Connecting the Mac
Connect the board's USB-C to your Mac, then start the harness and the CLI in two terminals. Remember that starting the harness resets the board. Wait for the boot to finish, or let connect wait for it (up to 120 s).
ls /dev/cu.usbserial-*
.venv/bin/python tools/vios_harness.py --backend resident \
--port /dev/cu.usbserial-210 --tcp 127.0.0.1:8765
.venv/bin/python tools/vios_cli.py
VIOS console — :help for commands.
vios> 2 3 + .
5
vios> :status
...
Type :help for the CLI commands. To let Claude use the board too, add the nc bridge to your MCP configuration. Both then share the one harness. See The Host Harness and MCP Tools.
Your startup file: /VIOS/USER.FTH
If /VIOS/USER.FTH exists on the SD card, VIOS loads it once at every boot. It runs after the saved modules are loaded and before AUTORUN starts. Use it for settings and small definitions that you want every time but that are not worth a module. An example:
\ /VIOS/USER.FTH: runs once at every boot, before AUTORUN
DECIMAL
: HELLO-USER ." Good morning from USER.FTH" CR ;
HELLO-USER
Put it on the card from the Mac with the CLI:
vios> :put user.fth /VIOS/USER.FTH
Wrote <n> bytes to /VIOS/USER.FTH sha256 <first 16 hex digits>
vios> :get /VIOS/USER.FTH
The CLI's :put uploads a local ASCII text file. Without the Mac, you can write the file from Forth with OPEN and WRITE-ALL (see Files and the SD Card).
Keep in mind:
- The file is loaded like
LOAD. It is at most 4096 bytes, and every definition must be complete by the end of the file. - If it fails, boot continues and the Console window shows
user startup failed:with the error. Fix or delete the file and reboot. USER.FTHdefinitions are compiled fresh at every boot. They are not modules: they have no version, test or rollback, and they do not show up inMODULES.
Starting an application at boot: AUTORUN
After USER.FTH, VIOS looks for a word named AUTORUN. If one exists, VIOS starts it as a console-attached background task (' AUTORUN SPAWN-CON) and prints autorun task N. The REPL stays usable next to it, and N TASK-KILL stops it. You can define AUTORUN in USER.FTH or in a saved module:
: AUTORUN ." autorun: ready" CR ;
A long-running application loops and yields with MS or PAUSE. Because it runs as a task, a bug in it cannot take the REPL away from you:
: AUTORUN BEGIN ." tick" CR 5000 MS AGAIN ;
See Tasks and Preemption for TASKS, TASK-KILL and task output.
Saving your first module
RAM definitions disappear at the next reboot. To keep code, make it a module: a named, versioned piece of source with an optional test word. VIOS checks a module on the C reference engine before it goes live, saves it to SD as an immutable package, and loads it at boot as part of a boot bundle. The full workflow is in Modules and Persistence. Here is the shortest path from the Mac, with the harness's develop tool:
{"name":"develop","arguments":{"name":"SQ","version":"1",
"source":": SQUARE ( n -- n*n ) DUP * ;\n: SQUARE-OK ( -- f ) 7 SQUARE 49 = ;\n",
"test_word":"SQUARE-OK","save":true}}
develop stages the module (it compiles and runs the test, which must leave exactly one true value), activates it, and saves the package to /VIOS. You can do the same on the board in the workbench editor (F1).
The module is now live and saved, but the boot bundle does not include it yet. Put all active modules into a new trial bundle, then reboot:
BOOT-TRIAL
REBOOT
During the next boot the trial bundle loads. When it passes the health check you see boot trial confirmed A (slot A on a fresh card; trials alternate between A and B), and from then on SQUARE is there at every power-on. If the trial had failed, VIOS would have printed boot candidate rejected: and booted the previous bundle. BOOT-STATUS shows the confirmed and candidate slots. BOOT-MANIFEST lists what the next power cycle will load.
A checklist for a new board
- The monitor shows the desktop with the Console window, and the console reaches
vios>. - Typing on the PS/2 keyboard echoes in the Console window.
BOOT-TIMESshows a total of a few seconds.- The Mac's harness attaches and the CLI answers
2 3 + .with5. - Optional:
.venv/bin/python tools/vios_board_suite.py build/suite-firstpasses every check (see The Host Harness and MCP Tools).