1
0
Fork 0
mirror of https://github.com/mrlima4095/OpenTTY-J2ME.git synced 2026-10-09 19:38:35 +00:00
OpenTTY Java Edition is a Terminal Emulator for J2ME Phones http://opentty.xyz
  • Java 49.7%
  • Lua 39.1%
  • C 6%
  • Assembly 1.3%
  • Shell 1.1%
  • Other 2.8%
Find a file
2026-10-09 11:42:15 -03:00
apps apps: show native netcat errors in LCDUI 2026-09-28 17:46:32 -03:00
build boot menu: drop countdown/auto-boot, wait for user click; back to single-level anonymous Runnable 2026-09-12 22:12:04 -03:00
dist Build "2026-1.18.2-04x42" - Release 1.18.2 - In Marluce's memory 2026-09-26 19:21:11 -03:00
docker Add pproxy as submodule (mrlima4095/pproxy) and proxy its routes via nginx 2026-08-27 21:24:13 -03:00
docs elf: build and test C socket apps 2026-09-28 14:47:46 -03:00
nbproject Build "2026-1.18.2-04x43" - 1.19 Suite Case 2026-09-26 19:31:20 -03:00
pc elf: marshal socket output to display thread 2026-09-28 16:54:25 -03:00
pproxy@5e7f6439f9 fix: repair pkg source loading 2026-09-05 10:52:46 -03:00
res apps: show native netcat errors in LCDUI 2026-09-28 17:46:32 -03:00
src elf: marshal socket output to display thread 2026-09-28 16:54:25 -03:00
tests elf: marshal socket output to display thread 2026-09-28 16:54:25 -03:00
tools x11: remove proxy support from current catalogs 2026-09-27 14:53:09 -03:00
.gitignore pc: run staged Lua/ELF apps and boot init=/root= via console or boot args; add desktop JAR build 2026-09-26 08:50:44 -03:00
.gitmodules Add pproxy as submodule (mrlima4095/pproxy) and proxy its routes via nginx 2026-08-27 21:24:13 -03:00
AGENTS.md pc: first boot asks to create user and password; boot menu + RMS persistence like the J2ME MIDlet 2026-09-26 12:33:10 -03:00
build-elf.sh elf: build and test C socket apps 2026-09-28 14:47:46 -03:00
build.sh build: clean stale classfiles before compile (keep ELF$1 out of lite jar) 2026-09-11 23:12:50 -03:00
CHANGELOG.md Build "2026-1.18.2-04x43" - 1.19 Suite Case 2026-09-26 19:31:20 -03:00
CITATION.cff OpenTTY reference 2026-01-01 11:40:09 -03:00
CODE_OF_CONDUCT.md opentty.fun 2026-06-09 18:35:24 -03:00
CONTRIBUTING.md docs: repository language convention - everything in English (AGENTS/CONTRIBUTING); memelf and cal headers translated to English 2026-09-24 15:40:25 -03:00
Dockerfile Fix docker build: allow pip system install on PEP 668 managed python 2026-08-27 22:24:37 -03:00
favicon.ico icon 2025-09-19 16:43:03 -03:00
index.php docs: update SDK CLI build instructions 2026-09-26 15:43:35 -03:00
LICENSE UPLOAD 2024-08-01 15:46:25 -03:00
proxy.php proxy.php 2026-01-07 16:33:09 -03:00
README.md pc: add run-jar.sh launcher that sets _JAVA_AWT_WM_NONREPARENTING for non-reparenting WMs 2026-09-26 18:46:59 -03:00
ROADMAP.md . 2026-10-06 21:36:43 -03:00
s60.php Add S60Tube search proxy 2026-09-14 08:06:16 -03:00
sdkcli.jar build: bundle local SDK CLI 2026-09-10 21:14:04 -03:00
SECURITY.md Security Page 2026-04-21 18:00:50 -03:00
server.py fix: secure user management and add xterm history 2026-09-04 20:59:58 -03:00

OpenTTY — Terminal Environment & RISC-V ELF Emulator for J2ME

License GitHub top language GitHub release (latest by date) Platform

OpenTTY is a complete, miniature operating-system environment that runs on Java ME (J2ME) mobile devices. It ships as a single MIDlet and bundles:

  • a POSIX-like shell with a virtual filesystem and process management,
  • a Lua 5.x interpreter tailored for low-memory devices,
  • a RISC-V RV32IM ELF emulator with a guest C runtime (lib32.s / libc.s),
  • graphics, network, and audio APIs.

All of it runs inside a constrained CLDC-1.0 / MIDP-2.0 environment, turning legacy handsets into a portable scripting platform.


Table of Contents


Features

Shell & Runtime

  • Lua 5.x interpreter with functions, tables, loops, and protected error handling
  • Virtual Unix-like filesystem (/bin, /boot, /etc, /home, /lib, /mnt, /tmp, /dev, /proc, /root)
  • Pipes, redirection, environment variables, and command execution
  • Multi-process environment with PID control and permissions

RISC-V ELF Emulator

  • RV32IM ELF executable loading (ET_EXEC, EM_RISCV 243, 32-bit LE)
  • Linux EABI syscall emulation on a 1 MB virtual memory with segment management
  • RV32I core + M extension (mul/div/rem), guest C runtime in res/lib/
  • Dynamic loading of -shared libraries (.so): DT_NEEDED, .rela.plt/.rela.dyn (RELA), R_RISCV_JUMP_SLOT/R_RISCV_COPY/R_RISCV_RELATIVE

File System

  • Hierarchical Unix-style layout with /proc virtual files
  • Persistent storage via RecordStore (RMS)
  • Real device file-system mounting (/mnt/, JSR-75)
  • VFS subdirectories under /bin, /etc, /lib that persist across restarts

Graphical Interface

  • LCDUI-based forms, alerts, lists, text boxes, and command handlers
  • Custom fonts, layouts, and screen management from Lua

Network

  • TCP/IP client and server sockets
  • HTTP/HTTPS client (socket.http)
  • Inter-process communication via os.request

Quick Start

First Run

  1. Install OpenTTY.jar on a J2ME-capable device (or run it in an emulator).
  2. On first launch you will be asked to create a username and password.
  3. Restart the MIDlet. Subsequent boots auto-log in the created user.

Hello World

print("Hello OpenTTY!")

-- Write to a file
local status = io.write("content", "/tmp/test.txt")

-- HTTP request
local response, code = socket.http.get("http://example.com")
print("Code:", code)
print("Response:", response)

File System

/
├── bin/      # System executables and scripts
├── dev/      # Virtual devices (stdin, stdout, null, random, zero, tty)
├── etc/      # Configuration (fstab, hostname, motd, os-release, vfs.conf)
├── home/     # User files (RMS RecordStores)
├── lib/      # Lua libraries and modules (libcore.so)
├── mnt/      # Real device file system (JSR-75)
├── proc/     # Virtual process/sysinfo files (cpuinfo, meminfo, uptime, <pid>/...)
├── root/     # Root user's protected home
└── tmp/      # Temporary in-memory storage

See File System documentation for details.


Shell Commands

Some of the built-in commands available in the shell:

Category Command Description
Process ps, bg, exec, kill Manage running processes
Users su, whoami, logname, id Switch and inspect users
Session exit Close the MIDlet / terminal
Shell alias, env/set/export, unset, eval, source, builtin Manage the shell
Files pwd, cd, cat, ls, touch, cp, rm, mkdir, nano File operations
Network curl, wget, nc, ping, ifconfig Network utilities
System uptime, free, uname, htop, gc, warn, title Inspect and control
Utilities echo, date, clear, true, false Basic utilities
Package yang / pkg Package manager

Install additional tools from the app store with pkg install <name> (e.g. pkg install nano, pkg install htop).


Lua API

Modules

Module Purpose Selected functions
os System operations execute, getenv, setenv, exit, date, getuid, su, request, setproc, getproc, mkdir, remove
io Input / output read, write, open, close, dirs, popen, copy, mount
string String manipulation upper, lower, sub, find, match, reverse, byte, char, split, hash, startswith
table Table manipulation insert, remove, concat, sort, pack, unpack, decode
socket Networking connect, server, accept, http.get, http.post, peer, device
graphics User interface display, new, append, addCommand, handler, render, vibrate
java Java integration class, getName, run, delete, midlet.*
base64 Base64 encoding encode, decode
push PushRegistry register, unregister, list, pending, setAlarm, getAlarm
audio Audio (MMAPI) load, play, pause, volume, duration

Note on string: this implementation does not provide string.format, string.rep, string.gsub, or string.gmatch. Use the native string.startswith / string.endswith rather than reimplementing them.

UI Example

local form = graphics.new("form", "My App")

graphics.append(form, { type = "field", label = "Name:", value = "" })
graphics.append(form, { type = "choice", label = "Options:",
                        options = { "A", "B", "C" } })

local save = graphics.new("command", { label = "Save", type = "ok" })
graphics.addCommand(form, save)

graphics.handler(form, { [save] = function() print("Saved!") end })
graphics.display(form)

RISC-V ELF Emulator

Features

  • RV32IM ELF executable loading (ET_EXEC, EM_RISCV, entry ≤ 1 MB)
  • RV32I instruction emulation plus M extension (mul/mulh/div/rem)
  • Linux EABI syscalls + library syscalls (LIB_BASE 1000: string/memory/printf/sprintf/malloc/RISC-V runtime helpers)
  • LCDUI guest ABI (res/lib/lcdui.h): Form, List, TextBox, Alert, fields, text items and commands with queued events. See docs/ELF/LCDUI.md for the C API and examples.
  • 1 MB virtual memory with segment management
  • Shared-library loading (.so): DT_NEEDED, RELA relocations, PLT/GOT
  • File descriptors and I/O
  • Registers (x0–x31, a7 syscall number)

Supported Syscalls (partial)

exit, fork, read, write, open, close, creat, time, gettimeofday, kill, getpid, getppid, getuid, brk, getcwd, chdir, nice, plus fstat/stat and network syscalls (bind, listen, accept, recvfrom, sendto, ...) under active development.


Package Manager

yang (also invoked as pkg) installs apps from the on-device app store:

pkg list                  # List available packages
pkg install nano          # Install a package (requires root)
pkg install *             # Install everything
pkg remove nano           # Remove a package
pkg update                # Check for updates
pkg download nano n.txt   # Download a package without installing
pkg info nano             # Show package information

Packages include nano, htop, curl, wget, nc, ping, find, grep, sed, viewer, x11, docker, and many more.


Security

  • Restricted execution environment — OpenTTY is a trusted terminal for old devices, not a hardened remote-access tool.
  • Password storage — credentials are hashed and stored in an inaccessible file.
  • No encryption — network traffic is not encrypted; use secure networks or a VPN.
  • Multi-user model — root (UID 0) has full access; regular users (UID 1000+) are restricted to their own files and processes.

Read the full Security policy and User system docs.


Building & Installation

Detailed instructions are in docs/BUILD.md.

Quick overview:

  • Build on-device using the J2ME SDK (http://opentty.fun/dl/SDK.jar)
  • Compiles to OpenTTY.jar + OpenTTY.jad
  • Install directly on Java ME (MIDP-2.0 / CLDC-1.0) devices
  • Version: 1.18.2

Desktop development

For fast iteration without a device, pc/run.sh boots the unmodified src/ MIDlet on a desktop JDK (17+) via the pc/j2me bindings:

pc/run.sh                                   # interactive boot (1st run: create user/password)
pc/run-jar.sh                               # run dist/OpenTTY-desktop-*.jar (sets the WM env var)
pc/run.sh --user opentty --pass opentty     # headless first boot, straight to console
pc/run.sh --smoke --user opentty --pass opentty -- /tmp/app.lua  # run a Lua app at boot + dump state
pc/run.sh -- /tmp/rvtest.elf       # stage + run a RISC-V ELF at boot
pc/run.sh init=./init.lua          # boot a Lua script as PID 1
pc/run.sh root=/path/to/rootfs     # chroot a host directory (root=)

Under non-reparenting WMs (bspwm, i3, dwm...) the window can open blank grey; run.sh sets _JAVA_AWT_WM_NONREPARENTING=1 to fix it (see docs/RUNNER.md).

Desktop niceties: the first run opens the “OpenTTY - Login” form to create a user and password (like the J2ME MIDlet, with an RMS persisting credentials and the VFS under data/rms); a boot menu (“OpenTTY - Boot”) appears whenever /boot/grub.cfg has several entries; Enter in the xterm input row runs the command (a focused Run button answers Enter too), the console output fills the window width with no left margin, and destroying the MIDlet (Exit/exit) closes the window instead of leaving a zombie JVM.

pc/build-jar.sh packs the same build into a standalone desktop JAR (dist/OpenTTY-desktop-1.18.2.jar, java -jar …). See docs/RUNNER.md for the full runner reference.


Documentation

Comprehensive docs live in docs/:

Also see the changelog and roadmap.


Contributing

OpenTTY is developed by the community. See CONTRIBUTING.md for guidelines on reporting bugs and submitting pull requests.

Author: Mr. Lima


License

MIT