![]() |
![]() (last updated 2025-06-07) |
![]() |
GeckOS is under active development; André recently
released version
2.2, so by now this page is quite out of date. You can
find the latest source in André's repo
on GitHub. In the
source, you'll find a directory named doc/
with
thorough documentation
in AsciiDoc.
GeckOS is a Unix-like 6502 operating system by André Fachat with preemptive multi-tasking, signals, semaphores, redirection, a standard library, and its own relocatable file format. It runs on the Commodore 64, PET, and 8296 machines, as well as a 6502 machine that André built himself. I gave a talk about it at VCFMW 2019; here are the slides and the video. I gave another talk at the World of Commodore show in Toronto (December 2019), highlighting some of the recent enhancements in GeckOS. Here are those slides and the video.
Building GeckOS
is straightforward. The xa
cross-assembler is used to build the operating system and to create
relocatable binaries for it. Its documentation
includes usage instructions as
well as a description of
the relocatable file
format. If you don't feel up to building GeckOS yourself, here's
a D64 image built from the
master branch of the Commodore 64 version as of 2020-07-15.
If you're interested in the internals of GeckOS, I've been working on an analysis of the source code, which is quite detailed (although still incomplete). Note that the analysis refers mostly to the 2.0.9 version; at some point I'll update it for the 2.2 version.
Tips for exploring GeckOS
Debugging GeckOS Programs
Using SLIP with GeckOS
LOAD"LOADER",8
and RUN
to start the operating system. Drives are a:
(devices), b:
(system programs),
and c:
through f:
(C=
devices 8 - 11). You can use 0:, 1:... if you're squeamish about
drive letters. uname
shows version
info; ls
shows a directory (it accepts
a -?
argument for help).C=/CONTROL
(i.e. hold down the
Commodore key and tap CONTROL). On startup, a shell
(lsh
)
runs on video1
, and
the older version of the shell runs
on video2
.
lsh
shell on console 3, use this
command from console 1 (>!
means to
redirect both stdout and stderr):
lsh <a:video3 >!a:video3 &
ontty
command:
ontty a:video3 c:lsh
lsh <a:ser1 >!a:ser1 &
lmon
(here
are
the docs).Here's how to find the addresses of code or variable labels in your GeckOS program. If you need to know an address before the program starts, you could wait for a keystroke at the beginning of your program like this:
#include "lib6502.i65" #include "apps/common.a65" ;for strout hitakey .( lda #hitkey jsr strout ldx #STDIN sec ;wait for keystroke jsr fgetc rts ). hitkey .asc $0a,$0d,"hit a key...",$0d,0
First, you have to assemble your program with the -l
flag to get a label listing. Run the file65
utility (part
of the xa
distribution) against the executable to find
the segment sizes. Here is the output for the examples I'll be
showing:
arch/c64/test/uiitest: o65 version 0 executable file mode: 0000 =[executable][16bit][byte relocation][CPU 6502][align 1] text segment @ $1000 - $11fc [$01fc bytes] data segment @ $0400 - $0535 [$0135 bytes] bss segment @ $4000 - $4228 [$0228 bytes] zero segment @ $0004 - $0008 [$0004 bytes]
This program waits for a keystroke on startup, so I switched to a
different console and ran the ps
command, which told me
that the program starts at $2C33
. Bear in mind
that ps
shows you the execution address, not the
load address. If you have a main
label and it's not at
the start of the program, you'll have to do a little more arithmetic
to get the load address.
The segments are contiguous in memory, so you can add the size of each one in turn to the load address, giving these numbers:
text: $2C33 text length: $01FC data: $2E2F data length: $0135 bss: $2F64
Note the (arbitrary) offset for each segment: you'll have to subtract it from the label's address, then add it to the segment address:
text: $1000 data: $0400 bss: $4000
I'll show how to find a label from the text (code), data, and bss
segments. First, the goahead
label, near the start of the
code (I have main
at the beginning). The label file shows
us this:
goahead, 0x102d, 1, 0x0002 subtract offset: $102D - $1000 = $002D add to start of text segment: $2C33 + $2D = $2C60The
banner
label, in the data segment:banner, 0x04cc, 1, 0x0003 subtract offset: $04cc - $0400 - $00cc add to start of data segment: $2E2F + $00cc = $2EFBThe
message
label, in the bss segment:message, 0x4200, 1, 0x0004 subtract offset: $4200 - $4000 = $0200 add to start of bss segment: $2f64 + 0200 = $3164
For zero-page variables, check the output of the GeckOS
build, which runs file65
against the ROM image (note that
these are absolute addresses):
c64rom.o65: o65 version 0 executable file mode: 0000 =[executable][16bit][byte relocation][CPU 6502][align 1] text segment @ $83fe - $10000 [$7c02 bytes] data segment @ $0300 - $0b13 [$0813 bytes] bss segment @ $0b30 - $1675 [$0b45 bytes] zero segment @ $0008 - $0067 [$005f bytes]You can see that zero-page variables start at $0008; add that to the zero segment offset in your program's
file65
output
($0004 in the example above), then add the label's address to
that. This may get more complicated; see the discussion
of zalloc
in
my commentary.
GeckOS has TCP/IP networking using SLIP, but it doesn't always behave (hint: testing would be appreciated!). André reports that it can be run in the VICE emulator:
x64sc -rsuser -rsuserdev 2 -rsuserbaud 9600 -rsdev3 "|socat - PTY,link=/tmp/viceser" -autostart osa.d64and the following csaip script as
sudo ./csaip -d /tmp/viceserYou can actually run VICE without any USB/serial hardware and still have it provide an sl0 network interface.
At least that's how it works on Linux. socat's PTY option creates a "master pseudo terminal" that slattach can then use to attach to the client side and create a network interface. Because socat uses "-" for STDIO, I can pipe in/out the RS232 emulation of VICE by specifying the VICE RS232 output device name with the "|".
The "link" option to socat just creates a symlink to the real pty file (as the name is not deterministic it seems), and the "readlink -f" command translates the symlink to that actual device file, as slattach does not follow symlinks.