Building and using GCC 0.9 aka the first public version

In my quest for old software, I’ve seen this file in multiple searches, gcc-0.9.tar.bz2, which is the first version of GCC!

article from virtuallyfun.superglobalmegacorp.com

GCC 0.9 on SIMH VAX / 4.2BSD

GCC 0.9 on SIMH VAX / 4.2BSD

From the original announcement:

 Date: Sun, 22 Mar 87 10:56:56 EST
From: rms (Richard M. Stallman)

   The GNU C compiler is now available for ftp from the file
/u2/emacs/gcc.tar on prep.ai.mit.edu.  This includes machine
descriptions for vax and sun, 60 pages of documentation on writing
machine descriptions (internals.texinfo, internals.dvi and Info
file internals).

   This also contains the ANSI standard (Nov 86) C preprocessor and 30
pages of reference manual for it.

   This compiler compiles itself correctly on the 68020 and did so
recently on the vax.  It recently compiled Emacs correctly on the
68020, and has also compiled tex-in-C and Kyoto Common Lisp.
However, it probably still has numerous bugs that I hope you will
find for me.

   I will be away for a month, so bugs reported now will not be
handled until then.

   If you can’t ftp, you can order a compiler beta-test tape from the
Free Software Foundation for $150 (plus 5% sales tax in
Massachusetts, or plus $15 overseas if you want air mail).

Free Software Foundation
1000 Mass Ave
Cambridge, MA  02138

[tapes are generally in Unix tar format.  If you have other needs,
write to the above address, and ask if they can be met. -len]

And indeed, the files are dated 22/03/1987 making this the first public release of GCC.

GNU CC is a fairly portable optimizing C compiler intended for
machines with 32-bit words that have several registers and address
memory in terms of 8-bit bytes.  It supports full ANSI standard C, not
including libraries (which we do not consider to be part of a
compiler).
Currently we have working machine descriptions for the Vax and for
the 68000/68020 (including 68881 support).
Optimizations performed by GNU CC include:

  • Invariant code motion out of loops.
  • Common subexpression elimination.
  • Automatic register packing (register declarations are unnecessary
    and ignored).
  • Constant propagation and elimination of consequent dead code.
  • Copy propagation.
  • Elimination of dead stores.
  • Jump optimization including cross-jumping.
  • Delaying of stack adjustments after function calls.
  • Arithmetic performed in subword types when appropriate.
  • Many local optimizations.

GNU CC runs about as fast as PCC.
Most of the optimizations are machine-independent or controlled by a
machine description.  GNU CC takes advantage of all the 68020
addressing modes that we can see how to make the Sun assembler
assemble.  Debugging output for DBX is available whether you request
optimization or not.

Seeing as 4.3BSD didn’t ship until 1988, I went ahead and set out to build this on 4.2BSD. The first stumbling block I hit is that GCC needs bison.  The oldest version of bison I have is 1.25 which honestly is just too new!  However in the same location as GCC is this file gnu1988.tar.bz2 which contains all of the current GNU software of 1988!  And what is on that tape?

  • bison-1.00
  • gcc-1.21
  • gdb-2.5.1
  • gplusplus-1.21
  • libgplusplus

So this is probably as old as it is going to get, so I downloaded and went to compile bison, however getopt is a missing call!  A creative search found getopt.c (local mirror) and even better PCC liked it enough to get a running bison so I could then configure GCC.

Configuring GCC is a manual process, but not too involved:

  • Make a symbolic link from file `config.h’ to the top-level
    config file for the machine you are using. Its name should be
    `config-MACHINE.h’. This file is responsible for
    defining information about the host machine. It includes
    `tm.h’.
  • Make a symbolic link from `tm.h’ to the machine-description
    macro file for your machine (its name should be
    `tm-MACHINE.h’).
  • Make a symbolic link from `md’ to the
    machine description pattern file (its name should be
    `MACHINE.md’)
  • Make a symbolic link from
    `aux-output.c’ to the output-subroutine file for your machine
    (its name should be `MACHINE-output.c’).Make sure the Bison parser generator is installed.Build the compiler. Just type `make’ in the compiler directory.

And in a minute I had GCC compiled.  I ran it with -v and got this output:

# gcc -v
ld /lib/crt0.o -lc
Undefined:
_main

It really is nowhere near as featured as 1.21 that is for sure!  So time to do a simple hello world program:

# cat hello.c
#include <stdio.h>
void main(){
printf(“GCC 0.9 in action!\n”);
}
# gcc -v hello.c -o hello
cpp -Dvax hello.c /tmp/cc002050.cpp
cc1 /tmp/cc002050.cpp -quiet -dumpbase hello.c -noreg -o /tmp/cc002050.s
as -o hello.o /tmp/cc002050.s
ld -o hello /lib/crt0.o hello.o -lc
# ./hello
GCC 0.9 in action!

And there we go!

I don’t know why, but I haven’t seen anything about anyone actually running GCC 0.9.  Or even where or how they found this ‘lost’ file. Â Let alone anyone even building or running it in 2016.

For anyone who wants to try, SIMH tape files of the binaries are here:

And of course source tapes are here.

Found EMX 0.8b

While cruising archive.org, I found this CD-ROM image, “OS/2 Archive CD-ROM Walnut Creek May 1992“, which included the following zoo files:

05/05/1992 09:46 AM 144,272 EMXDEV.ZOO
05/05/1992 09:44 AM 167,809 EMXINFO.ZOO
05/05/1992 09:46 AM 101,132 EMXLIB.ZOO
05/05/1992 09:46 AM 19,266 EMXTEST.ZOO
05/05/1992 09:46 AM 586,285 GNUDEV.ZOO
05/05/1992 09:40 AM 78,575 GNUPAT.ZOO
05/05/1992 09:41 AM 138,891 GNUSRC1.ZOO
05/05/1992 09:41 AM 184,671 GNUSRC2.ZOO
05/05/1992 09:45 AM 1,044,875 GNUSRC3.ZIP
05/05/1992 09:43 AM 1,015,692 GNUSRC3.ZOO
05/05/1992 09:42 AM 505,127 GNUSRC4.ZOO
05/05/1992 09:45 AM 3,178 README.DOC

And from the readme, the release is from Feburary of 1992.  Keeping in mind the GA release of OS/2 2.0 was released in April of 1992.

EMX 0.8b INTRODUCTION 22-Feb-1992

Welcome to emx, a common environment for creating 32-bit programs for OS/2 2.0
and MS-DOS. You can use the GNU C compiler to compile programs for EMX.

Included in the emx package are:

  • emx.dll dynamic link library for OS/2 2.0
  • emx.exe DOS extender for running 32-bit programs under MS-DOS
  • emxbind.exe for creating .exe files which work both under OS/2 2.0 and
    MS-DOS
  • C header files and a nearly complete C library, including source

Additionally, the following GNU programs are available compiled and with
sources (note that these files are not part of EMX):

  • gcc, the GNU C compiler
  • gas, the GNU assembler
  • gdb, the GNU debugger
  • ld, the GNU linker
  • ar, nm, size, strip, objdump: some GNU utilities for dealing with binary
    files
  • Patched source for gcc, gas, gdb, ld, ar, nm, size, strip, objdump. You can
    compile all these programs with the files that come with emx (but you also
    need a make utility, such as NMAKE)

So this pretty much sums it up.  I went ahead and extracted the ZOOs and placed a copy on my site: emx08b_extracted.7z  Although I don’t think anyone really cares about ancient versions of GCC on OS/2.

EMX 0.9d rehosted on Win32

EMX on Win32

I know it’s utterly pointless… But yeah GCC 2.8.1 + EMX 0.9d, hosted (running) on Win32.  The main reason is that I wanted to be able use use my substantially faster Win64 machines to build stuff for OS/2.  And since I have a 4 core (+4 hyper thread), I want to be able to use make with the -j 16 flag, and say compile QuakeWorld/2 in under two seconds.

I was able to get the binutils 2.6 derived stuff to compile, along with the ‘ancient’ binutils which is notably the linker that EMX depends on.  I would imagine this ought to be able to compile PDOS, although my own simple attempt at InfoTaskForce met with spectacular failure.  While it does compile fine using an older EMX 0.8h based release.

EMX 0.9d on Windows 10 x64

EMX 0.9d on Windows 10 x64

As you can see, it can compile the dhyrstone benchmark, and run the MS-DOS version via the MS-DOS Player.

Downloads

N64 cross GCC / Binutils for Win32

Building GCC & Binutils for the Nintendo 64

I had a request to help get a GCC+Binutils running as native win32 exe’s something comparable to the ancient ‘ultra’ N64 toolchain done by Kyoto Microcomputer (resume pdf).  One interesting thing about their toolchain is that they used a common object format for MS-DOS, DOS/V and MS-DOS on the PC-98 format, along with Win32.  However, the Win32 runtime doesn’t like Win64 environments.  On Win64 the exew32 driver just complains:

Can’t allocate memory (Error Code=487)

However the stubs in all the exe’s reference exegcc98 exegccv DOS extender’s along with a exegcc. However, googling around yields nothing.

Running on a x86 version of Windows, however the tools run and report gcc 2.7.2 release 1.2 and the binutils version is simply 2.6 with BFD version 2.6.  So going with this, and the request to keep it 1997 vintage I went ahead with Gcc 2.7.2.3 and Binutils 2.8.1 as they are the end of the line in both trains of code.

To configure is really a snap, as both support the Windows NT platform directly

sh configure --host=i386-winnt3.5 --target=mips-elf

I guess I should add that I build with TDM GCC 5.1, and I use the incredibly ancient MSYS-1.0.11-rc-1. It’s enough to bootstrap and build with!  Since my GCC is much newer, I did have to finagle some things.  Here is a quick list of my notes on what I had changed, and some justification.

Binutils 2.8.1 notes:

include/fopen-same.h

make sure this uses MS-DOS rb wb type constraints!

libiberty/xmalloc.c

There is no sbrk on my MinGW32 … so comment out all the sbrk stuff.

bfd/targmatch.sed

My sed LOVES UNIX style text files, so this one shouldn’t be in MS-DOS CRLF format.

binutils/objcopy.c

mkdir only accepts the path on Win32.  Also there is now chown.

Gcc 2.7.2.3 notes:

c-gperf.h

‘__inline’ for is_reserved_word needs to be commented out.

config/mips/mips.h

Set like the following for both ASM_FINAL_SPEC to prevent the t-mips from trying to be run.

#define ASM_FINAL_SPEC “\
+%{pipe:-}”

config/winnt/xm-winnt.h

OBJECT_SUFFIX “.o”

Just because we are on Windows NT, doesn’t mean we want an .obj object suffix.

gcc.c

__spawnv : __spawnvp work better as _spawnv : _spawnvp

obstack.h

*((void **)__o->next_free)++ = ((void *)datum);

confuses newer compilers, with this error message:

obstack.h:341:32: error: lvalue required as increment operand

replace it with with:

*(__o->next_free)++ = ((void *)datum);

So at the end I have a cross compiler, and I can generate object files, and link files that the final tool MILD can then use and produce N64 ROM images.  It’s not a 100% solution, as I don’t see any mention of MILD being GNU, however the compiler and binutils is running on Windows 10 x64!

GCC cross compiling to the N64 target

GCC cross compiling to the N64 target

I built a few demos and tested with the 1964 emulator.

And there you have it.  For anyone who cares, you can download the toolchain + source here: winnt3.5_i386-mips_elf-gcc-2.7.2.3_binutils-2.8.1.7z

Starting on an ELF cross compiler for Windows

I’m using Slackware 4.0 as a starting point, so it’s Binutils 2.9.1 and GCC 2.7.2.3 .. I verified that I can build a static hello world executable, and it runs! …

However Linux 2.0.40 has the same issue, it starts to decompress, and triggers a reboot in both Qemu and PCem.  Going in circles I guess.  I suppose the next step is to use the exact version they have in Slackware to see if Qemu can actually run that pre-built kernel, and if I can create one via cross compiling.

I should add that on Debian 7.1 I got GCC 2.7.2.3 running, and it too produces the exact same thing.

Not that I think anyone cares, but here is my pre-built toolchain with some source (The binutils was built under Linux, using a MinGW cross compiler) elfgcc_2.0.40.7z

Cross compiled Linux 1.0.9!

Linux 1.0.9 running!

Linux 1.0.9 running!

After getting Linux 0.98 to compile, I thought I’d take a stab at Linux 1.0.  I vaugely recall when it was released, and I just remember a much larger push to 1.1.  So I guess it really comes as no surprise that in the Linux kernel archives, there is simply the 1.0 tar, and 9 patch files.

I went ahead, and patched up the release, and then tried to build with GCC 2.3.3.  This however proved not to be up to the task, as 2.3.3 has issues with some of the assembly macros, so delving into the readme shows that you need to use GCC 2.4.5 or higher.  Since I wanted to keep at least the tools on par, I went ahead and build 2.4.5, and once more again used the gcc driver from 2.6.3.  I further ended up relying on headers, and checking tool versions from Debian 0.91, which also revealed that they were still using GAS 1.38 back then.

One interesting note while building piggback, which takes the compressed system object, and wraps it in an object file, is that it directly uses the magic “0x00640107”, which is for a later “Linux/i386 impure executable (OMAGIC)” filetype.  But because my binutils is so ancient, I needed to change it to “0x00000107” so that the linker would recognize it as a “386 executable not stripped” file.  As always when having no idea what I was doing, it was easier to have it make an empty object file, set the type for 12345678 and look for where it occurs in the data stream, and just match it with a known object file.  As you can see, it worked.

I don’t know if it is of any interest, but the kernel source, along with a binary is available to download linux-1.0.9.7z, and the same goes for GCC gcc-2.4.5.7z.

And of course, you’ll want the latest download, which includes the pre-built tools, qemu, and build environment to get you started.

Cross compiling Linux 0.95c+ & 0.96c from Windows

The first thing is to build GCC 2…  I couldn’t find any of the Linux patches for 2.0, 2.1 or 2.2.. I only tried to build 2.0 from source as targeting a.out i386 but it looks like the 2.0 files on the FSF’s site are missing files?

Anyways GCC 2.3.3 actually includes builtin support of Linux!  I was able to build most of it, but just like GCC 2.5.8 for OS/2 EMX, But this time I used the gcc driver from GCC 2.6.3, which added support for Windows NT 3.5 native builds, and I now had my GCC cross compiler!

D:\aoutgcc\src>gcc2 -v -c hi.c -o hi
gcc version 2.6.3 -Linux 2.3.3
cpp2 -lang-c -v -undef -D__GNUC__=2 -Dunix -Di386 -Dlinux -D__unix__ -D__i386__ -D__linux__ -D__unix -D__i386 -D__linux hi.c C:\Temp\cca09324.i
GNU CPP version 2.3.3 (80386, BSD syntax)
cc12 C:\Temp\cca09324.i -quiet -dumpbase hi.c -version -o C:\Temp\cca09324.s
GNU C version 2.3.3 (80386, BSD syntax) compiled by GNU C version 5.1.0.
a386 -o hi C:\Temp\cca09324.s

Thankfully the prior binutils and assembler I was using in my GCC 1.40 cross compiler, still cooperated just fine, and I could happily build and link just fine.

From there it was a matter of fighting the makefiles as for some reason as make calls other makefiles they are not passing variables, so I just cheated, and changed the paths, along with editing the dependencies to finding stuff in a more sane manner.  Plus all the Makefiles have include paths hard coded into the build process as expected.  After fighting for a while, it linked and even better, it runs!

linux-0-96c-71-cross-compiled-from-windows

Linux 0.96c-71 cross compiled from windows

So yeah, using the MCC hard disk image from oldlinux.org and it boots!

Cool stuff, indeed!

As an added bonus I was also able to get 0.97 & 0.98 to compile as well!

Download your copy @ MinGW-aout-linux–001_010_011_012_095_096_097_098.7z.

Mariko’s x68000 GCC 1.42 on Windows

Yes, I probably need a better hobby.

D:\proj\142\gcc-1.42_x68000>gccnew.exe -v -c x.c
gcc version 1.30 Tool#2(X680x0)
hcpp.exe -v -undef -D__GNUC__ -Dmc68000 -Dhuman68k -DHUMAN68K -DMARIKO_CC -Dmariko_cc -D__mc68000__ -D__human68k__ -D__HUMAN68K__ -D__MARIKO_CC__ -D__mariko_cc__ x.c C:\Users\jason\AppData\Local\Temp\x.cpp
GNU CPP version 1.30 Tool#2(X680x0)
hcc1.exe C:\Users\jason\AppData\Local\Temp\x.cpp -quiet -dumpbase x.c -fhuman -version -o C:\Users\jason\AppData\Local\Temp\x.s
GNU C version 1.30 Tool#2(X680x0) (HAS Ver 3.XX syntax)
compiled by GNU C version 5.1.0.
default target switches:
x.c: 5: Message:ì┼ôKë╗é═ìséφéΩé─éóé▄é╣é±
run68 has.x -e -w -u -i . C:\Users\jason\AppData\Local\Temp\x.s -o x.o
D:\proj\142\gcc-1.42_x68000>run68 ..\hlkb\hlk301.x x.o CLIB.L
D:\proj\142\gcc-1.42_x68000>run68 x
Hello x68000 from GCC 1.30 Tool#2(X680x0)!
D:\proj\142\gcc-1.42_x68000>ver

Microsoft Windows [Version 10.0.10586]

I’ve gotten the compiler to build natively as a win32, however the assembler & linker are x68000 programs that I run via run68.  libgcc.a is missing so there is no floating point support at all.  I have to figure out how to generate it.  Right now it’s using the SHARP/Hudson libraries on the C Compiler PRO-68K ver2.1 disks.

I don’t think this will be of value to anyone, but for the hell of it, you can download my incredibly rough port here.

gcc142_x68000.7z You really want this one instead: gcc-1-30-x68000

Linking doesn’t work by default, so you have to manually link, as what I did above.

Linux 0.01 remake

While further searching around on Linux 0.01, I came across DrAcOnUx’s site which features a Linux 0.01 remake!

It’s really great, first off there are several versions in the steps of the evolution of the project:

Linux-0.01-1.x :
– need gcc 1.4
– few change from official linux-0.01, only some bug fix, + minor change to build it in a linux system instead of minix

Linux-0.01-2.x :
– same version as linux-0.01-1.7, which was just ported to work with gcc-2.x and gcc-3.x

linux-0.01-3.x :
– this is the last version
– need gcc-4.x
– use elf binary format instead of a.out, and you have some program working on it

As I actually do have a working GCC 1.40 + Binutils I though it would be great to build his first phase on Windows.  With a little playing around in the makefiles, and the build program to open files in binary mode, I had a kernel!

Linux 0.01 remake

Linux 0.01 remake

Obviously there is issues with the executables that I have from Linux 0.10/Linux 0.11.  But we are mounting the disk, and using the /dev tree devices.  I put the remake versions on my cvsweb to walk though what changed.

Using an older ‘modern’ Linux machine with GCC 4.1 I was able to compile the remake #3 kernel, and even better with the provided disk image from the downloads page it works!


# gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

Linux 0.01 remake #3

Linux 0.01 remake #3

For any aspiring software historians out there, this early version of Linux from September of 1991 will be of course VERY interesting!

Linux 0.01 on Qemu!

Well sort of.

Linux 0.01!

Linux 0.01!

I looked at the source again, and for some reason 99% of it compiled without issue.  I recall having all kinds of issues, but clearly I was doing something wrong back then.  At any rate, all I really had to do was modify the commenting style in the 8086 boot block code, and modify the image creation tool to open files in O_BINARY mode for Windows, and I got an image that will boot, then panic because it has issues reading the hard disk.  I tried the seemingly small ‘fix’ from Linux 0.11 but it’s not working.

If anyone cares, I updated the sourceforge download, as MinGW-aout-linux–001_010_011.7z