| Mode | Name | Size | |
|---|---|---|---|
| -rw-r--r-- | .clang-format | 729 | logstatsplainblame |
| -rw-r--r-- | .gitignore | 18 | logstatsplainblame |
| -rw-r--r-- | Makefile | 1956 | logstatsplainblame |
| -rw-r--r-- | README.md | 6026 | logstatsplainblame |
| d--------- | demo | 79 | logstatsplain |
| d--------- | docs | 40 | logstatsplain |
| d--------- | hooks | 38 | logstatsplain |
| d--------- | include | 36 | logstatsplain |
| -rw-r--r-- | shot.ppm | 69135 | logstatsplainblame |
| d--------- | src | 730 | logstatsplain |
| d--------- | tools | 363 | logstatsplain |
| d--------- | usr | 2243 | logstatsplain |
gbos
A tiny Unix-flavored OS for the Game Boy Color — a from-scratch cooperative microkernel with fork/exec, a shell with pipes, a persistent filesystem, a color terminal on the LCD, and a real TCP/IP stack over the link cable. It boots, gets a DHCP lease, pings, resolves DNS, fetches web pages, and hangs out on IRC. On a 1997 handheld (well, an emulated one).

Real capture: cold boot → DHCP lease → ping → an IRC session, typed live
into the on-screen console. Regenerate it anytime with tools/gbdemo (below).
What's in the box
- Processes, the V7 way:
fork/exec/wait/exit, zombies + reaping, background jobs (spin &),ps,kill— round-robin cooperative scheduling across banked memory with an HRAM context switch. - A shell (written in C, running on the GB) with I/O redirection
(
><>>) and pipes (|), argument passing, and a cwd-aware prompt — withgrepto put on the other end of the pipe,teeto fork it, andmoreto page anything longer than the 18-row screen. - Shell scripts: a shell fed from a file (
sh < script) runs it with no prompt and no echo, and init runs/rcat boot if the cart has one — so a Game Boy can come up with its own startup script. - Networking, for real: the kernel owns SLIP over the link port, IPv4,
ICMP, UDP and TCP; userland gets BSD-ish sockets via one syscall. On top:
dhcp(boot-time lease),ping,nslookup(real DNS),wget(HTTP),nc(netcat:nc HOST PORTinteractively, ornc -s HOST PORT < fileto pipe a request in and print the reply),chat, and a colorized IRC client (irc HOST [NICK],/joinand friends, SELECT for the keyboard). - It serves, too: the kernel does passive opens (
listen/accept, one socket per client), so the Game Boy runs daemons.httpdputs the cart's filesystem on the web —httpd &, then point a browser at it: files come from battery-backed RAM, directories as clickable listings.ircdis a real IRC server —ircd &, thenirssi -c 10.0.0.2: NICK/USER/JOIN/ PRIVMSG/PING/NAMES/PART/QUIT, with the channel relayed between clients. A laptop and a second Game Boy can sit in the same channel, hosted by a Game Boy. - A network to plug into:
tools/gbhubis a virtual switch + DHCP server + NAT gateway — spawn a fleet of Game Boys that ping each other and reach the real internet;tools/gbjoinattaches an interactive GB to it, andtools/gbtypetypes into any GB's shell from the host. - 40×18 color terminal on the LCD (4×8 font, two chars per tile, ANSI-ish colors) + an on-screen keyboard on the window layer (SELECT toggles it).
- Persistent filesystem on battery-backed cart RAM: inodes, nested
directories, per-process cwd — survives power-off (files up to 3 KiB).
ls -landdfreport sizes and free space;poweroffis the only safe way to stop the machine (the battery save is written on a clean exit). /binin the tree: the builtins are not files on the disk, but they show up as one anyway —ls /binenumerates the kernel's own command table,cd /binworks, andxxd -l 16 /bin/unamedumps the program's ROM bank. Read-only, since it is ROM.- A C toolchain: userland is plain C compiled with SDCC (
sm83); ~50 tools ship inusr/(cat,wc,head,tail,grep,cp,mv,tee,tr,cut,uniq,rev,more,ls,df,xxd,touch,sleep,uptime, …) —helplists them all on the Game Boy itself. Adding a program is one.cfile + a table entry.
Quick start
git config core.hooksPath hooks # once: clang-format pre-commit hook
make # -> gbos.gb (needs RGBDS + SDCC)
# solo, in the sl0pboy emulator (~/dev/gbc):
~/dev/gbc/build/sl0pboy --sixel 3 --chrome gbos.gb
# networked — hub in one terminal, Game Boys in others:
sudo tools/gbhub --daemon # virtual net + DHCP + NAT (needs root)
tools/gbjoin # a windowed GB joins 10.0.0.0/24
tools/gbtype 'ping 10.0.0.3' # or type into it from the host
# serve the Game Boy's filesystem to your browser:
tools/gbtype 'httpd &' # then open http://10.0.0.2/
curl http://10.0.0.2/readme # files straight out of cart RAM
# or host an IRC network on it:
tools/gbtype 'ircd &' # then, from the host:
irssi -c 10.0.0.2 # /join #gbos
tools/gbtype -g 1 'irc 10.0.0.2 gb2' # a second GB joins the same channel
On the Game Boy: SELECT toggles the on-screen keyboard, d-pad + A types, START sends the line.
/# uname -a
gbos sm83 (Game Boy Color)
/# ping 10.0.0.1
PING 10.0.0.1
reply from 10.0.0.1 seq=1
...
-- 4/4 received
/# irc 10.0.0.1 sl0pboy
-!- registering as sl0pboy (SELECT = keyboard)
The demo GIF
The GIF above is produced by a scripted, self-syncing demo driver:
tools/gbdemo runs a step file (demo/readme.gbd), injects console text and
button events at the right moments — syncing on the actual screen contents
(the terminal's WRAM shadow, read over the emulator's debug socket) rather
than timers — while the emulator records every frame, then renders the GIF:
sudo tools/gbhub --daemon # network up (once)
tools/gbdemo demo/readme.gbd # inside tmux; writes demo/gbos-demo.gif
Edit demo/readme.gbd to choreograph your own (verbs: type, slowtype,
key, waitfor, record, gif, …).
Docs
- docs/internals.md — the full technical breakdown: memory model, syscall ABI, fork/exec/context-switch internals, the network stack, the filesystem layout, C toolchain notes, war stories, roadmap.
Built and tested against the sl0pboy emulator; runs on anything that emulates a CGB + MBC5 cartridge with battery RAM. No MMU, no protection, no regrets.
