Today's objective has been to get RMoX built with the most recent toolchain. I've succeeded, but I've found lots of broken stuff along the way that'll need fixing properly.
When Fred last built RMoX, he documented the build process on the RMoX web pages. These instructions (presumably) work with the software versions he lists, but quite a lot has changed since in the occam-pi world: we've had a new stable release of KRoC, for instance.
Assembling the pieces
I'm going to assume that you're doing this all in your home directory; it should be pretty obvious what to change if you're doing this elsewhere.
You'll obviously need the RMoX source. I'm working from the latest RMoX
source in the Subversion repository on rmox-dev
, but you'll also need the
latest RMoX release tarball off the web site, because the toplevel
Makefile
is missing from the repository.
You'll need the KRoC source (even if you've got it already
installed). I first tried kroc-1.3.4-pre1.tar.gz
, the latest
prerelease, but that won't compile some of the RMoX code owing to an
interesting bug; get kroc-1.3.3.tar.gz
instead.
The problem is that Fred enabled some internal checks in occ21 in this
release that weren't previously present, and this exposes some
previously-harmless compiler bugs. The particular one that I ran into
building RMoX was a refusal to compile CLONE
followed by an array
subscript (for example, CLONE a[0]
). This is the result of a bug in
the cmobileio
function in chk2.c
: occ21 tries to ensure that if
the argument to CLONE
is a channel, then it must be a shared
channel, but in the process it assumes that the argument to CLONE
is
a single variable name, which isn't true in this case. It looks like
it'd be possible to fix this problem by using something like
chk_gettype
(which finds the declaration corresponding to the type
of an expression elsewhere in the parse tree).
Finally, you'll need the Flux OSKit. This hasn't been maintained by
its original authors for a couple of years, but the GNU Hurd
developers have a
patched version on Savannah which compiles with modern versions of
GCC and binutils and has a few new features. Check it out from their
CVS repository into a directory called oskit-source
.
Building KRoC
A normal KRoC build will do nicely. If you've got KRoC 1.3.3 installed already, then you don't need to do this.
Before you build KRoC, take a copy of the src/ccsp-1.6
directory. RMoX requires a specially-built ccsp runtime, and we'll
want to modify it in a minute.
cd ~/kroc-1.3.3
cp -a src/ccsp-1.6 ~/
./build --prefix=$HOME/kroc133
. ~/kroc133/bin/setup.sh
Building the OSKit
The Savannah OSKit very nearly works out of the box, but it doesn't
succeed in building the multiboot-to-zImage adaptor that KRoC needs in
order to generate a zImage, because it tries to use ld -oformat
binary
when that should actually be --oformat
on modern binutils.
Patching this and then building the result is easy:
cd ~/oskit-source
perl -i.bak -pe 's/-oformat/--oformat/g' configure
CC=gcc-2.95 ./configure --prefix=$HOME/oskit
perl -i.bak -pe 's/-oformat/--oformat/g' boot/linux/*
make
make install
It doesn't really need installing -- RMoX links stuff and runs scripts straight out of the build dir -- but the aforementioned adaptor scripts look for a boot image in the installed path.
I'm not sure if it's necessary to use GCC 2, but it certainly doesn't hurt; OSKit is very much GCC 2-era code.
Preparing the RMoX source
The RMoX source in the repository at the moment needs some twiddling to be buildable (the code's fine; it's just the build system that's broken).
CCSP will need some RMoX headers, but it tries to include oos/x.h
instead
of x.h
; we drop a symlink into the RMoX source to deal with this.
cd ~/rmox/include
ln -s . oos
The RMoX repository is also missing the toplevel Makefile, so we copy that
from Fred's released source. We need to edit the OSKIT
and KROC_CCSP
variables in there to point at the right paths too ($(HOME)/oskit-source
and $(HOME)/ccsp-1.6
respectively). We run the config-building script
provided to generate config.mk
from config.occ
. Finally, we create empty
DEPS
files in each of the source directories; the Makefiles aren't set up
to correctly autogenerate them (the target's called depend
, not DEPS
),
and doing make depend
will fail because it tries to include the
nonexistent files.
cd ~/rmox
cp ~/rmox-0.1.2/Makefile .
vim Makefile
cd occam
touch DEPS
for x in */ ; do touch $x/DEPS ; done
Building CCSP
The CCSP source needs modifying for the OSKit environment. The problem is
that KRoC on Linux uses siglongjmp
to return from a signal handler, but
the OSKit doesn't provide siglongjmp
, sigsetjmp
or sigjmp_buf
. The
first two don't matter, but the last does, because the bsc_thread
structure declared in include/i386/bsyscalls.h
has a sigjmp_buf *jbuf;
member. Find this, and change it to char jbuf[156];
. (That's just to keep
the structure size the same; I haven't yet investigated whether it'd be safe
to just remove the member for RMoX.)
cd ~/ccsp-1.6
vim include/i386/bsyscalls.h
Then we can build it:
./preconfigure
./configure --enable-oos-build \
--with-oskit=$HOME/oskit-source \
--with-oos=$HOME/rmox
make
And now we have to build the specific version of CCSP as a library that RMoX needs, and copy it into our RMoX source directory:
make libkroc_oos.a
cp libkroc_oos.a ~/rmox/
While doing this, I noticed that CCSP's autoconf setup is broken: the
--enable-blocking-syscalls
option actually disables blocking syscalls
(because the arguments to AC_ARG_ENABLE
are backwards). Not that this
matters much, because CCSP won't build without BSC anyway.
Building RMoX
Now that we've done all the dependencies, we should be able to compile the RMoX occam source:
cd ~/rmox/occam
make depend
make
For some reason, with KRoC 1.3.3, most of the symbols we need don't end up
in librmox.a
, so we just add all the object files to that library:
ar cru librmox.a *.o */*.o
Now we can build the zImage:
cd ..
make
Running RMoX under qemu
Now you should have a functioning RMoX zImage. And you don't even need another PC to prove it's working: RMoX runs fine under Fabrice Bellard's incredibly cool qemu PC emulator, provided you pad it to be the right size for a disk image first:
cat zImage /dev/zero | dd of=disk bs=1k count=1440
qemu -fda disk
Which looks like this: