Documentation

OkamaOS Reference

Architecture, boot sequence, package format, OTA updates, controller input, Bluetooth, and security boundaries — everything developers need.

Introduction

What is OkamaOS?

OkamaOS is a controller-first Linux console OS built on Buildroot for x86_64 low-cost PCs. It replaces the conventional Linux desktop stack with a single-purpose game console loop — no desktop, no window manager, no terminal in normal mode.

The system boots directly into okama-shell, a fullscreen SDL2/Pygame UI. Games are installed as .ok packages — self-contained tar archives with a typed manifest. Updates arrive as .okupdate bundles served from this portal's public JSON feed.

Key Principles

  • Controller is primary. Keyboard allowed only for text entry and emergency navigation.
  • One game at a time. Lock file prevents concurrent game processes.
  • No desktop. No X11, no Wayland, no compositor, no WM.
  • Games get priority. Non-essential services suspended on launch.
  • .ok packages are cartridges. Install, run, remove — predictable lifecycle.
  • Public update channel. All OS and game updates verifiable via SHA-256 hashes.

Supported Hardware

Target: x86_64 PCs with 256 MB+ RAM, USB or Bluetooth gamepad, HDMI/VGA display, and optionally Wi-Fi. Live USB boot or hard-drive install via okama-install. Tested in QEMU and on physical x86_64 hardware.

System Design

Architecture

OkamaOS consists of four main layers: the Buildroot-compiled kernel and rootfs, the init system and services, the okama-shell UI, and the game runtime.

Component Map

ComponentRoleEst. RSS
okama-shellFullscreen SDL2/Pygame game console UI~70 MB
okama-runGame lifecycle manager — launch, lock, recover<5 MB
okama-cliAdmin and debug CLI<5 MB
okama-inputdController daemon, evdev → JSON socket~12 MB
bluetoothdBlueZ 5 stack (started only when needed)~30 MB
dhcpcdDHCP client for network~3 MB
kernel + driversHID, DRM, ALSA, USB, Bluetooth~60 MB
Total idleWell under 250 MB budget~185 MB

Key Invariants

  • One game at a time: /var/run/okama-game.lock
  • No desktop: no X11, no Wayland, no compositor
  • No terminal in normal mode: tty2 getty only in developer mode
  • Games get scheduling priority; non-essential services suspended on launch

Startup

Boot Sequence

UEFI/BIOS firmware
       ↓
  SYSLINUX (hidden, no menu in normal mode)
       ↓
  Linux 6.6 kernel (quiet, loglevel=0)
       ↓
  BusyBox init  →  /etc/inittab  →  /etc/init.d/rcS
       ↓
  S10okama-mounts   (proc, sys, devtmpfs, tmpfs /run)
  S20okama-devices  (eudev or mdev)
  S25okama-bluetooth (only if enabled or paired controllers exist)
  S30okama-inputd   (controller daemon → /run/okama-inputd.sock)
  S35okama-audio    (ALSA init, master unmute)
  S40okama-network  (DHCP, optional WiFi — skipped if disabled)
  S99okama-shell    (okama-shell on tty1, respawn on crash)
       ↓
  okama-shell  (fullscreen SDL2/Pygame controller UI)
       ↓
  [user selects game]  →  okama-run  →  game process
       ↓
  [game exits / crashes]  →  okama-run recovers  →  okama-shell resumes

Silent Boot

Kernel uses quiet loglevel=0. Init.d output is redirected to a boot log (/var/log/okama-boot.log). The user sees only the Pygame splash, then the shell.

Live USB Persistence

If a partition labelled OKAMA_DATA exists on any attached storage, early boot mounts it at /var/okamaos. This enables live USB builds that persist games, saves, and config across reboots without a full hard-drive install.

Storage

Filesystem Layout

/                          (read-only rootfs — v1 target)
├── etc/okamaos/           OS config (okama.conf, parent.conf, devmode.conf)
├── usr/bin/               okama-* binaries (Python scripts)
├── usr/lib/okamaos/       shared Python library (okamaos.*)
├── usr/share/okamaos/     themes, templates, assets, controller-icons
└── var/okamaos/           (read-write data partition)
    ├── games/             installed .ok packages (extracted)
    ├── saves/             per-game save_state.json
    ├── logs/              shell, game, crash logs
    ├── cache/             download cache
    ├── controllers/       paired Bluetooth controller profiles (.json)
    └── updates/           staged OTA update bundles and backups

Config File: /etc/okamaos/okama.conf

Key configuration values read by all okama-* tools:

KeyDefaultDescription
UPDATE_NOTIFICATIONSyesEnable periodic update checks
BLUETOOTH_ENABLEDnoStart bluetoothd on boot
STORE_URL(portal URL)Game Store catalog source
DEV_MODEnoEnable developer mode (tty2, unsigned packages)

Game Packaging

The .ok Package Format

.ok files are ZIP or tar+gzip archives with the .ok extension. Okama Studio exports ZIP-format packages. The runtime auto-detects format via magic bytes.

game.ok
├── manifest.ok.json        ← required
├── main.py                 ← entry point (or path from manifest "entry")
├── assets/                 ← optional (images, sounds)
├── icon.png                ← optional (128×128 game icon)
├── banner.png              ← optional (460×215 store banner)
├── controller.json         ← optional (button layout hints)
├── save_hook.py            ← optional (save/restore hooks)
└── site-packages/          ← optional (bundled pip deps)

Manifest

manifest.ok.json Schema

{
  "name":               "My Game",
  "id":                 "com.publisher.mygame",
  "version":            "1.0.0",
  "runtime":            "okama-sdl2",
  "entry":              "main.py",
  "min_ram_mb":         64,
  "target_fps":         30,
  "permissions":        ["controller", "audio", "save_data"],
  "age_rating":         "Everyone",
  "supports_save_state": true,
  "controller_required": true,
  "keyboard_usage":     "none",
  "description":        "Short description shown in the shell."
}

Validation Rules

RuleEffect on failure
Missing required fieldReject install
ID not reverse-DNS (lowercase, dots)Reject install
Runtime not in supported listReject install
Age rating not in {Everyone, Teen, Mature}Reject install
Unknown permission nameReject install
controller_required = false outside dev modeReject install
Entry path contains .. or starts with /Reject install
Path traversal in archive membersReject on extract

Execution

Runtime IDs

Runtime IDDescription
okama-litePython 3, no graphics — logic or CLI games
okama-pythonPython 3 + pygame, standard launch
okama-sdl2Python 3 + pygame + full SDL2 feature set (recommended)

v1 will add okama-native for compiled C/C++/Rust games. Okama Studio generates okama-sdl2 manifests by default.

Development

Host Development (no Buildroot)

All okama-* tools are plain Python 3 scripts. Run them on any Linux host with Python 3.10+:

bash
export PYTHONPATH=$PWD/usr/lib
export OKAMA_CONF=$PWD/board/okamaos/rootfs-overlay/etc/okamaos/okama.conf

# Run the admin CLI
./usr/bin/okama-cli status

# Build and verify a .ok package
./usr/bin/okama-pack build games/demo --output /tmp/demo.ok
./usr/bin/okama-pack verify /tmp/demo.ok

# Run the shell in a host window (requires pygame)
pip install pygame
PYTHONPATH=$PWD/usr/lib ./usr/bin/okama-shell --windowed

System Updates

OTA Updates & Rollback

OkamaOS uses this portal (GitHub Pages) as its public update source. Devices check https://zyntrixsolutions.github.io/okamaos/updates/feed.json when UPDATE_NOTIFICATIONS=yes.

Manual Update Check

dev console
okama-update check

Apply an Update

Download the .okupdate bundle from this page's Updates section, then apply it. Protected user data (games, saves, controllers, config) is never touched.

dev console
# Dry run first — inspect what will be replaced
okama-update apply --dry-run okamaos-v1.3.0.okupdate

# Apply with hash verification
okama-update apply --sha256 7311537148ec04ca436bb21fd31ee115a412fcd33cc9a2c3420077b46928666b okamaos-v1.3.0.okupdate

Rollback

Every non-dry apply writes a backup under /var/okamaos/updates/backups/. Rollback restores the latest backup:

dev console
okama-update rollback

Protected Paths (never overwritten)

  • /var/okamaos/games — installed games
  • /var/okamaos/saves — game save data
  • /var/okamaos/controllers — Bluetooth controller profiles
  • /var/okamaos/updates — update history and backups
  • Parent PIN config, developer config, Wi-Fi credentials

Input System

Controller Input

okama-inputd is the central controller daemon. It scans /dev/input/event* every 2 seconds, spawns one reader thread per device, translates raw evdev events through controller-profiles.json, and broadcasts unified JSON events over a Unix socket.

Unified Button Protocol

{"type": "button", "button": "A",       "state": "pressed",  "controller": 0}
{"type": "button", "button": "DPAD_UP", "state": "released", "controller": 0}
{"type": "axis",   "axis":  "LSTICK_X", "value": -0.87,      "controller": 0}
{"type": "connect",    "controller": 0, "name": "Xbox Controller", "bus": "usb"}
{"type": "disconnect", "controller": 0}

Canonical Button Names

OkamaXboxPlayStation
AACross
BBCircle
XXSquare
YYTriangle
L1 / R1LB / RBL1 / R1
L2 / R2LT / RTL2 / R2
STARTStart/MenuOptions
SELECTBack/ViewShare/Create
DPAD_UP/DOWN/LEFT/RIGHTD-padD-pad

Shell Navigation Conventions

UI ActionController Input
Move cursorD-pad or LSTICK
Select / OKA
BackB
HomeSTART or HOME
Quick menuSELECT
Tab left / rightL1 / R1
Page up / downL2 / R2

InputClient API (for game developers)

python
from okamaos.input_protocol import InputClient

client = InputClient()
if not client.connect():
    pass  # okama-inputd not running — use pygame.joystick fallback

while game_running:
    for event in client.poll():
        if event["type"] == "button" and event["state"] == "pressed":
            if event["button"] == "A":
                do_select()
        elif event["type"] == "axis":
            move_player(event["axis"], event["value"])
# InputClient.poll() is non-blocking — call every frame

Wireless Input

Bluetooth Controllers

OkamaOS uses BlueZ 5 (bluetoothd) for Bluetooth HID controller support. The stack is started only when BLUETOOTH_ENABLED=yes in okama.conf, or when paired controller JSON files exist in /var/okamaos/controllers/.

Pairing via CLI

dev console
okama-cli bluetooth status           # check adapter power state
okama-cli bluetooth scan             # scan 15 s, list found devices
okama-cli bluetooth pair <mac>       # pair; auto-trusts
okama-cli bluetooth connect <mac>    # connect immediately

Auto-Reconnect

On boot, S25okama-bluetooth iterates over *.json files in /var/okamaos/controllers/ and calls bluetoothctl connect <mac> for each. Connection attempts are non-blocking — a missing controller does not delay boot.

Supported Controllers

  • Generic USB HID gamepads (automatic, no config)
  • Xbox USB and Xbox One S/Series X Bluetooth (hid-microsoft)
  • Sony DualShock 4 and DualSense (hid-playstation, kernel 5.16+)
  • Nintendo Switch Pro Controller (hid-nintendo, kernel 5.16+)

Access Control

Security Model

CapabilityNormalDev ModeParent PIN
Install signed .ok
Install unsigned .okRequired
Enable developer modeRequired
Access tty2 shell
Factory resetRequired
Bluetooth pair (if restricted)Required
Run arbitrary scripts

Developer Mode

Developer mode is enabled via Settings → Developer with a parent PIN. It unlocks tty2 access, unsigned package installs, and the interactive dev console. Dev mode state is persisted in /etc/okamaos/devmode.conf.

v1 Signing Design

game.ok
├── manifest.ok.json
├── MANIFEST.sha256     ← SHA-256 of every file, signed by publisher
├── SIGNATURE           ← Ed25519 signature against OkamaLabs root CA
└── CERTIFICATE.pem     ← publisher cert chain to root CA