J2ME · ARM32 Emulation

Run ELF & Lua
inside retro terminals

OpenTTY brings a full Unix-like environment to J2ME feature phones. Execute ARM32 binaries, Lua scripts, manage processes, and experience modern CLI on old devices.

Lua J2ME · ELF loader · Dynamic linking
root@opentty:~/home/#
$ uname -a
Nokia 6233 (OpenTTY 1.18.1) main/mod 2026-1.18.1-03x27 - CLDC-1.1 MIDP-2.0

$ ./hello.elf
Hello from ARM ELF on J2ME!

$ lua -e 'print(os.date())'
Tue Apr 30 16:20:01 2026

$ ps
PID  PROCESS
1    init
1420 lua script.lua
status: running

Designed for constrained devices,
powerful emulation

OpenTTY provides an unprecedented experience on J2ME phones: ELF loader, dynamic linking, POSIX syscalls, and full Lua environment.

ARM32 ELF Loader

Full ELF interpreter for ARM executables. Support for PT_LOAD, dynamic sections, GOT/PLT lazy binding, and syscall translation layer.

Lua J2ME

Complete Lua interpreter with coroutines, tables, metatables, and custom modules: `os`, `io`, `socket`, `graphics`, `audio`, `push` API.

Virtual FS & RMS

In-memory filesystem, persistent RMS storage, `/bin`, `/etc`, `/home`, and real FileConnection for memory cards. Full Unix-like paths.

Network Sockets

TCP/UDP socket support, HTTP client, socket server API. Connect, bind, send/receive syscalls mapped to J2ME GCF.

GUI & Graphics

Interactive UI via `graphics` module: Forms, Lists, TextFields, Images, Commands with callback handlers, LCDUI integration.

Process isolation

Multi-process model with UIDs, signalling, priority handling, and kernel IPC via request() mechanism. Sandboxed execution.

Hybrid execution engine

The core of OpenTTY includes a lightweight ARM32 interpreter that reads ELF binaries, relocates symbols, resolves dynamic libraries, and traps syscalls. Combined with the Lua runtime, it offers both compiled C applications and scripting.

  • Dynamic Linking: DT_NEEDED, GOT/PLT, lazy resolution, R_ARM_JUMP_SLOT
  • Full ARM Thumb/ARM mode: Data processing, load/store, branch, SWI syscalls
  • Signal handling & setjmp/longjmp
  • POSIX emulation: open, read, write, mmap, fork, execve, socket, futex
Explore source code
Dynamic relocation demo
// ELF relocation handling (Java)
switch(type) {
  case R_ARM_JUMP_SLOT:
    setupLazyBinding(gotOffset, symIndex);
    break;
  case R_ARM_GLOB_DAT:
    symAddr = resolveSymbol(symName);
    writeIntLE(memory, offset, symAddr);
    break;
}
// PLT resolver stub
0xe51ff004 : ldr pc, [pc, #-4]
OpenTTY implements both REL and RELA relocations, dynamic symbol table, and a generic syscall dispatcher with 70+ Linux EABI syscalls.

"OpenTTY brings the Unix philosophy to feature phones. It's more than a terminal — it's a full development and runtime environment for ARM binaries and Lua, all running inside the JVM."


J2ME ecosystem
MIDP 2.0 / CLDC 1.1 compatible
Modular design

ELF loader – independent bytecode interpreter – posix file abstraction – Lua FFI – graphics toolkit. Everything structured for extensions and lightweight memory usage (dynamic heap, 1MB base memory).

#ARM32 #LuaJIT-like #RecordStoreFS #Socket API

Building OpenTTY from Source Code

Compile OpenTTY directly on your mobile device using the official SDK tool

Download SDK

Get SDK.jar and transfer it to your device's storage or SD card.

Access Repository

Open file manager, navigate to the OpenTTY source folder. Ensure all Java files are present.

Compile with SDK

Launch SDK.jar, browse to OpenTTY directory, press the Build button (🛠️ hammer icon). Wait for compilation.

Output Files

After success, check the dist/ folder:

  • OpenTTY.jar – main executable
  • OpenTTY.jad – descriptor file
Installation

Method 1: Open OpenTTY.jar directly → install → launch.

Method 2: Use OpenTTY.jad for devices that prefer JAD installers.

✅ After install, find "OpenTTY" in your apps → start terminal.
Troubleshooting: verify source files & memory
JAD vs JAR: try alternate method
MIDP-2.0 / CLDC-1.1 required

Start building with OpenTTY

Get the latest release, browse the repository, or test the web proxy. All resources are open-source and community-driven.

Quick setup
# compile using mobile SDK.jar
$ java -jar SDK.jar (on phone via J2ME runner)
$ select OpenTTY folder → click Build (🛠️)

# output: dist/OpenTTY.jar + OpenTTY.jad
# install on any MIDP 2.0 device