KallistiOS: FAQ
1. About this FAQ
We're going to stick to the most basic and commonly asked questions here.
For really detailed stuff, you should look at the examples, read the KOS
headers, and ask on the mailing list or IRC Channel.
2. Compiler / Setup
2.1. What KOS version should I use?
KOS 2.0.0, which was released on May 23, 2013 represents the first stable
release of KOS in ten years time. It is a vast improvement over 1.2.0, and
should be a good choice for anyone who wants to make sure nothing changes
underneath of them at any point soon. If you're planning on making something
and releasing it to the world, this might be a good choice.
Despite the "in development" warning signs all over it, the source code in
the Git repository is also relatively stable. If you want to keep up with the
latest and greatest features, then this is where you want to be.
There is pretty much no good reason to be using older versions for current
development, and they probably won't work with more recent compiler versions
anyway. You're welcome to do so, of course, but you probably won't find much
help in doing so.
2.2. Why all this cruddy compilation, shell scripts, makefiles, oh my? Can't you just build it into a nice package so it's easy to set up?
Short answer: no. Longer answer: GCC is Unix software. It's more or less
written to assume it will be compiled not only on each major platform, but
on a specific version of a platform. So we *may* be able to produce nice
pre-compiled packages for your platform, but they may also fail mysteriously
due to dependencies. Dan tried that a few years back with KOSWIN and decided
to give up on it.
That said, you will probably have the most luck if you are using someone's
precompiled setup by getting the latest Cygwin (for win32), using an
up to date Linux distribution, or with a recent Mac OS X.
2.3. What version of GCC do I need? Newlib? Binutils? KOS? Yikes!
Yes, it's all very confusing at first. Unfortunately there's not really
a very easy way to simplify it all. The simplest answer here is to check the
KOS web pages and ask around about what's working for people. My
current setup (and thus the "canonical" one) is the following: sh-elf GCC 4.7.3
in kos threads mode, sh-elf binutils 2.23.2, newlib 2.0.0 (patched for KOS), and
KOS the Git repository.
And to gather and build it all, We recommend the dc-chain Makefile that is
included with KOS (in the utils/dc-chain directory). It has various scripts to
download and unpack the latest tested pieces of everything (except KOS itself)
and patch/build it. As long as you have a reasonably sane system with a working
version of GCC (and the prerequisites to build GCC), it should "just work". As
for GCC prerequisites (since they seem to be the most common problem), you'll
need a normal POSIX-like environment and a couple of libraries (GNU Multiple
Precision library, MPFR and MPC). More information on that can be found at the
GCC Website
Prerequisites page.
2.4. But.. but... I have GCC 10.30.4 that's newer, and I wanna use it!
That's great! You're on your own. Please join the mailing list and let us
know how it works out for you, we might upgrade too. :) Until that time, the
only supported config will be the one listed above because most of the KOS
users and developers are using it, and it's been very well tested. Interim
and older versions of GCC are known to have serious compilation bugs on the
SH platform, and newer versions have a bad tendency to develop them.
2.5. Ok, I've got a compiler set up and I'm trying to build KOS. But it's giving me some error about not finding /Makefile.prefab and it quits pretty fast after starting to compile.
You probably haven't set up your environ.sh properly (or at all). Again
check the KOS setup guide and make sure you have the right variables by typing
"set" by itself and looking for lots of KOS_* variables. KOS_BASE should
point to the base of your KOS tree (containing Makefile.prefab and such).
Newer versions try to detect this and spit a human-readable error.
2.6. I'm getting errors compiling things in utils. What to do?
It happens... that stuff is built for the host PC, not the DC. So sometimes
your platform doesn't have the libraries it needs by default, it needs
different flags, etc. Your best bet is to tinker around there and if you
can't get it working, post on the mailing list. If it's anything besides
genromfs, you can also probably just comment it out of the utils Makefile and
go on with your life, at least to start with.
2.7. Why don't you make KOS use a normal make / make install system? What's with all the environment variables and build kludges?
Basically the initial goal was to make it as excruciatingly simple to
set up as possible. Believe it or not, everyone hasn't used KOS since the
dawn of the DC scene. ;) So a lot of people would want to just download it
and try it, and not clutter up their compiler install. To that end, KOS also
included its own libc, libm, and other pieces, and thus also needed special
Makefiles to build your programs properly.
Nowadays, it's pretty much crushed all of its competition, so we've
started to look towards making it more of an installable product, and
duplicating less code. That's why it now uses an external Newlib for its libc
and libm, and it conforms to more POSIX functions each release (to ease
porting of unchanged libraries). So in a way, it makes more sense that it
will eventually become something you can install into your compiler tree.
But due to inertia and being simpler to switch among KOS trees, we still
have the environ.sh setup. It's really not too bad once you get used to it,
and worse comes to worse, you can always just make KOS_BASE point to a
place in your compiler tree. The GNU wrappers (kos-cc, kos-c++, etc) take
care of adding all the necessary compilation parameters, so there is also
no real need for a special Makefile anymore.
2.8. I have things like libpng installed on my machine already. Do I really need kos-ports still?
Yes, you do. There are two separate worlds involved in DC homebrew: your
host PC and the target DC. These two words will appear over and over if you
start looking into the tool chain, so learn them well! :) When you say you
have libpng installed on your machine, that is a host library. It is very
likely incompatible with the DC's processor and KOS' API. The reverse is true
of target libraries in kos-ports.
Sometimes you can get away with mixing headers between the two worlds,
but that's not very recommended. It's asking for trouble.
3. Getting Started With Code
3.1. The examples seem to be out of date or don't compile right. Where can I find some more up to date examples?
Unfortunately, right now you can't. The KOS 2.0.x API represents a
fairly stable version, but it's been in flux for a long time; so chances are,
sample code you come across on the net is out of date for the latest
version.
That said, the examples all should compile, assuming you have compiled the
entire kos-ports tree. If they don't let us know!
3.2. So how the @#%*@ do I figure out what I'm doing??
Whoa, calm down. Trust me, I know how you feel. :) The good news is, not
all the news is gloomy. The "hello" example is still pretty valid, to get
a basic project set up. If you want to do 3D, "parallax" and "tsunami" are
both pretty modern. The "lua" examples should still work, for basic scripting
support. And "ghettoplay-vorbis" under "sound" shows (if in a somewhat
drunken-code fashion) how to get OGG playback working. There's not a very
good example of the modern controller input API (maple) but the parallax and
tsunami example trees have a bit, and you could grab a copy of the Feet of
Fury public source release for that.
Hopefully the awful example situation will be rectified sooner or later!
4. Using KOS
4.1. What all is supported on the Dreamcast? What about peripheral X?
The answer is very likely "yes" these days. The main things not supported in
the main tree are the light gun and the Dreamcast Karoke unit. The former of
these has been mostly figured out. You can find patches to add the support by
looking around a bit. The Dreamcast Karaoke unit, however, is an area that
could still use some research.
Specifically, several previously stubborn pieces of networking hardware
are now pretty much fully supported. The Broadband Adapter, LAN Adapter, and
modem (up to 33.6Kbps) work quite well. Using the built-in network stack, you'll
actually have more hardware support out of the box for LAN networking than
pretty much any Sega official product. PPP support for the modem is pretty much
stalled at this point, due to lack of time/interest.
Some homebrew peripherals are also supported, like the DC Navi rewritable
flash BIOS and IDE adapter. These are enabled by setting subarch to "navi".
The more exotic peripherals are generally not supported. This includes
things like the zip drive (did it even exist outside a lab?), and maracas
(though these should mostly work as regular controllers).
5. Debugging
5.1. Is there a debugger?
Not really. You can build GDB and use the gdb stub over a serial connection
to get rudimentary debugging, but it's not what you're going to be used to
unless you're an olde Unix hacker(tm). :)
If in doubt, printf is your friend. ;)
5.2. My program crashed! Help! What can I do?
Well, first of all make sure you're getting the stdout output from KOS
when you run your program. You'll know if you've got this.
Now then, there are four basic kinds of crashes: unexpected
exit (including kernel panic), assertion failure, infinite loop, and
exception.
For unexpected exit, just look at the stdout output. You can usually
figure out what's going on there. If it doesn't give you enough info then
try searching for the likely-looking error string in the KOS source tree.
Sometimes the extra context helps.
For assertion failures, usually the message is pretty explanatory. You
can compile with frame pointers enabled (check environ.sh files in the KOS_BASE
dir) and get an actual stack trace for context. See "exception" below for
more info on what to do with this.
For infinite loops, your main quest is to get your program to break so
you can figure out where it's crashing. This is pretty easily accomplished
by installing a controller callback. This is called any time the user presses
a certain combination of buttons (assuming IRQs are enabled, which is usually).
See the Parallax font example for an example of this. Once you have a crash,
see "exceptions" below.
For exceptions, look for the PC and PR values. These are the code pointer
to the instruction that caused the crash (or sometimes, the instruction after
it), and the return address (i.e. one step up the stack). Use the
sh-elf-addr2line utility to get a source location:
sh-elf-addr2line -e my.elf 8c010152
If it comes back with "???" then you've likely corrupted your stack
pointer somewhere, or you jumped to an uninitialized function pointer, etc.
You can also check the assembly output:
sh-elf-objdump -d -S my.elf | less
Then type /^8c010152 (or whatever the address was) and hit enter. This
should jump down to the place in the code where it died. Sometimes looking
at the other registers in the exception output can help diagnose this.
If you really can't make any sense of how it got where it got or how the
compiler generated some code, you *may* have a compiler bug. Go ahead and post
to the KOS list about it.
You may also have a malloc issue. See below.
5.3. Are there tools to help find memory leaks, buffer overruns, etc?
Yes! You'll need to have built your own KOS to use it though.
You have two options: turning on debugging in the standard malloc, and
replacing malloc with a debug version.
The former is definitely the recommended choice for most usage, and it's
not a bad idea to leave it on while developing. Edit kernel/libc/koslib/malloc.c,
and look at the #define's at the top. 'DEBUG' turns on internal checks in
the malloc functions (mostly assert statements). These are basic and not
too helpful unless you have a catastrophic failure. KM_DBG enables KOS
memory debugging. This turns on "canary" zones before and after each block
and tracks all allocated blocks in a linked list to find leaks. Combined
with the INIT_MALLOCSTATS flag, you can see exactly where a piece of
memory was allocated, which thread allocated it, the size, and so on. Using
the sh-elf-addr2line util mentioned above, it's easy to hunt down where the
leak happened. KM_DBG_VERBOSE is like a sledge hammer to KM_DBG's claw
hammer. You have to enable both to make it work, and it prints to the
console every single time a malloc related function is called. This
obviously completely kills the speed of your program but it might help
you find a stubborn problem.
The latter option, debug malloc, is the Hole Hawg to KM_DBG_VERBOSE's
sledge hammer. The main thing it's good for is finding pieces of code that
double-free blocks and code that writes to dangling pointers. It does this
by never actually freeing any memory, but putting it on a "freed" list.
Needless to say this is pretty worthless in a program of any size, but if
you can track down the offending code to a small area it can be invaluable.
It's enabled by commenting out malloc.o from kernel/libc/koslib/Makefile, and
changing kernel/mm/Makefile to the second option.
On second thought, it looks like that 'mm' tree isn't even built in the
latest KOS. So you're on your own if you want to try it. ;) If you get it
working I'd love to get a patch.
6. KOS Hacking
6.1. What's the lay of the land on this thing?
KOS' source tree is organized into two top-level sections: kos and
kos-ports.
The 'kos' tree contains KOS itself. This includes build utils and such.
Everything in the 'kernel' tree will be built into libkallisti.a, which is linked
into your program. Architecture/platform (arch) generic headers are located
in 'include'.
Under 'kernel', things are split into arch-specific, and arch-generic
parts. The arch-specific parts are in 'arch/<arch>', where the
<arch> you're probably interested in is "dreamcast". Arch-generic
pieces are just in the 'kernel' dir, organized by subsystem.
Inside the arch/<arch> dir (aka "the arch dir"), the organization
is somewhat loose. But every arch will contain an 'include' dir, inside of
which is an 'arch' dir (the contents of which are fairly uniform across
different platforms) and a platform dir (the contents of which are very
specific to the given platform). Also the arch dir contains a "kernel" dir
that has arch-specific pieces that support the arch-generic part of the
kernel.
The kos-ports tree simple contains directories with things to build. Any
subdir of this dir which contains a "kos" dir is considered a port to be
built. That top-level port dir (e.g. libjpeg) should include a Makefile
built from the ports Makefile.prefab, and the "kos" dir should contain a
*.cnf file for each arch that's supported. So e.g. a library could have a
dreamcast.cnf which gives DC-specific built instructions. The rest of the
structure of each port is specific to the port in question.
6.2. I did something cool. How can I submit a patch?
Yay! Doing my work for me, I like that. I like it so much that I'll
often go to ridiculous lengths to clean up a bad patch for inclusion,
depending on what it is. But it helps a lot if you follow these simple
guidelines:
Please make the patch against the newest version possible. This could
be a weekly snapshot or a copy of the subversion repo (the latter is
obviously preferable, but I can live with the former).
Don't modify the file unnecessarily and try to conform to the style
of the file(s) you're changing. I like to think of this as the "Minimum
Necessary Change" principle (see: Asimov's End of Eternity :). If some
change is not absolutely necessary, weed it out before submitting; if
you don't, I'll have to! If you submit a patch that has what I consider
to be gross C formatting, I'll likely run it through 'indent' and you may
not like the result.
When building a patch, use the "-ruN" diff arguments. If you're diffing
against a Git copy, use "git diff".
Submit patches to the patch tracker on SourceForge. This will add a
permanent record of the patch that everyone can investigate to find the
status of it, and it also sends a notification email to the KOS list so that
a maintainer can look at it.
7. Licensing
7.1. What's the deal with the KOS licensing? Can I use it in my commercial game? Don't I need to pay for that?
It's simple; yes; and no, respectively. All of KOS itself (the pieces
you link into your target DC app, and most of the host PC utils) are under
the KOS license. This is basically a 3-clause BSD license with different
author credits. The only responsibility you have is to credit the KOS
authors somewhere in your program (either in the program itself or in
your documentation). That's it, really! Even local modifications you make
don't need to be submitted to us, though of course we'll appreciate it.
Though if you make interesting enough changes, it may be
reverse engineered out or otherwise duplicated anyway ;)
Everything else is under its own license (namely, kos-ports). You should
check the license of each of those items before using them. For example things
that used to be part of KOS or its examples (like libkosh and libconio) are
all KOS licensed. But some pieces (like the MP3 playback) are *GPL* licensed.
Others, like plib, are LGPL with various exceptions.
Bottom line, it's pretty lenient and easy, but do a little due diligence
first!
|