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.
.okpackages 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
| Component | Role | Est. RSS |
|---|---|---|
okama-shell | Fullscreen SDL2/Pygame game console UI | ~70 MB |
okama-run | Game lifecycle manager — launch, lock, recover | <5 MB |
okama-cli | Admin and debug CLI | <5 MB |
okama-inputd | Controller daemon, evdev → JSON socket | ~12 MB |
bluetoothd | BlueZ 5 stack (started only when needed) | ~30 MB |
dhcpcd | DHCP client for network | ~3 MB |
| kernel + drivers | HID, DRM, ALSA, USB, Bluetooth | ~60 MB |
| Total idle | Well 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:
| Key | Default | Description |
|---|---|---|
UPDATE_NOTIFICATIONS | yes | Enable periodic update checks |
BLUETOOTH_ENABLED | no | Start bluetoothd on boot |
STORE_URL | (portal URL) | Game Store catalog source |
DEV_MODE | no | Enable 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
| Rule | Effect on failure |
|---|---|
| Missing required field | Reject install |
| ID not reverse-DNS (lowercase, dots) | Reject install |
| Runtime not in supported list | Reject install |
| Age rating not in {Everyone, Teen, Mature} | Reject install |
| Unknown permission name | Reject install |
controller_required = false outside dev mode | Reject install |
Entry path contains .. or starts with / | Reject install |
| Path traversal in archive members | Reject on extract |
Execution
Runtime IDs
| Runtime ID | Description |
|---|---|
okama-lite | Python 3, no graphics — logic or CLI games |
okama-python | Python 3 + pygame, standard launch |
okama-sdl2 | Python 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+:
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 consoleokama-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.
# 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:
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
| Okama | Xbox | PlayStation |
|---|---|---|
A | A | Cross |
B | B | Circle |
X | X | Square |
Y | Y | Triangle |
L1 / R1 | LB / RB | L1 / R1 |
L2 / R2 | LT / RT | L2 / R2 |
START | Start/Menu | Options |
SELECT | Back/View | Share/Create |
DPAD_UP/DOWN/LEFT/RIGHT | D-pad | D-pad |
Shell Navigation Conventions
| UI Action | Controller Input |
|---|---|
| Move cursor | D-pad or LSTICK |
| Select / OK | A |
| Back | B |
| Home | START or HOME |
| Quick menu | SELECT |
| Tab left / right | L1 / R1 |
| Page up / down | L2 / R2 |
InputClient API (for game developers)
pythonfrom 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 consoleokama-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
| Capability | Normal | Dev Mode | Parent PIN |
|---|---|---|---|
Install signed .ok | ✓ | ✓ | — |
Install unsigned .ok | ✗ | ✓ | Required |
| Enable developer mode | ✗ | — | Required |
| Access tty2 shell | ✗ | ✓ | — |
| Factory reset | ✗ | ✗ | Required |
| 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