Cross compiling to BSD on Windows (BOW) from Win32

On the heels of discovering BOW, I thought I’d try to make a cross compiler. Attempts at running binaries on *BSD systems had mixed results, although I thought it was interesting that my old Linux a.out cross compiler can generate object files BOW can happily link, although anything more complicated resulted in disaster. As part of that project I had build a 386BSD 0.1 cross so I figured that’d be worth a shot.

And it worked!

Sor for the two or three people who care here we go!

bow-win32-cross.7z

I’ve been using DOSBox as it makes shuffling files through the dfs much more easier to test stuff.

hello world

First a simple hello world

I should break down how to build this with a super involved and unnecessarily complicated Makefile!

# File: Makefile (unix version)

CC = gcc
CC1 = cc1
AS = a386
CPP = cpp

LD = ld

EXE = hi

OBJ =	 hi.obj


CFLAGS= -O -m80387
INCLUDES = -I../../include
CPPFLAGS = -v -undef -D__GNUC__ -Dunix -Di386 -D__unix__ -D__i386__ -D__386BSD__
LIBS = -L..\..\lib -lc -lgnulib -lm
CRT0 = ../../lib/crt0.o

$(EXE): $(OBJ)
	$(LD) -o $(EXE) $(CRT0) $(OBJ) $(LIBS)

%.obj: %.c
	$(CPP) $(INCLUDES) $(CPPFLAGS) $< $*.i
	$(CC1) $*.i -quiet $(CFLAGS) -version -o $*.S
	$(AS) $*.S -o $*.obj


clean:
	@rm $(EXE) $(OBJ) *.S *.i

dclean:
	@rm /f $(OBJ) *.S *.i

I’ve broken this up into each of GCC’s phases (programs) so that I can inspect the output of each as I go. This also lets me control exactly what gets passed where. And in this case forces the use of the 80387 where/when needed. It’s also nice to see where and what gets pulled in by the C pre-processor what magical numbers are set, and of course to see how the calling conventions work in the resulting assembler file. While I had built this around the idea of cross compiling the 386BSD 0.1 kernel, it’s still fascinating to me that it can be hammered into making BOW compatible executables. Although I didn’t update the CPP flags, no doubt I probably should as the headers probably expect something more FreeBSD.

Running make yields:

C:\bow\src\hello>make
cpp -I../../include -v -undef -D__GNUC__ -Dunix -Di386 -D__unix__ -D__i386__ -D__386BSD__ hi.c hi.i
GNU CPP version 1.39
cc1 hi.i -quiet -O -m80387 -version -o hi.S
GNU C version 1.39 (80386, BSD syntax) compiled by GNU C version 7.1.0.
default target switches: -m80387
a386 hi.S -o hi.obj
ld -o hi ../../lib/crt0.o hi.obj -L..\..\lib -lc -lgnulib -lm

C:\bow\src\hello>size hi
text    data    bss     dec     hex
24576   4096    0       28672   7000

C:\bow\src\hello>wsl file hi
hi: a.out little-endian 32-bit demand paged pure executable not stripped

C:\bow\src\hello>

It should also probably be worth mentioning that the linage of BOW has to be in the dark days of the AT&T v CSRG/BSDi lawsuit as this toolchain does produce binaries that run, unlike the 1.0 phase of both NetBSD/FreeBSD where they dumped all the prior code and forked harder from the common 386BSD 0.1 that we all loved.

fib

Simple Fibonacci sequence

Inform ’87 interpreter

My favorite ZIP interpreter

NS32016 emulator

Now this one is interesting it’s a NS32016 emulator! I left the ns32016 cross in the data directory if you want to generate the data file. I was surprised it worked, but wow!

phoon

Phases of the moon may not seem all that exciting at first, but the big thing is the handling of the math coprocessor, and of course to be sure to link against the BOW libm. Otherwise it just hangs the system.

trek

And of course the old TREK game from Unix lore.

I would imagine that a newer version of GCC or at least CC1 should be easy enough to build, and of course cross compiling gives you an out of the 16MB RAM limit that WINMEM32 imposes.

The biggest WTF I had was for Hack 1.03. I’m not sure why it didn’t want to link, but rest assured, the cross compiled objects just linked fine. I don’t know.

In other BOW news I have been in contact with the author, I don’t want to bother him too much but I’ll try to glean a lot more info from him.

Leave a Reply