Getting Started on Linux/390

Bigfoot is one of two incompatible ports of the Linux operating system kernel and development tools to the ESA/390 IBM Mainframe Architecture. The Bigfoot port is also referred to as "i370" and is not advanced enough for general use. However, it is advanced enough for general hacking. The other port is IBM's port, called "s390".

The two are incompatible. The s390 port only runs on newer hardware; it i370 port does not use the new-fangled instruction set extensions, and thus should work on old hardware. The i370 port uses an assembly language style that is similar to the syntax used by HLASM, and thus should be almost trivial for regular mainframe programmers. The s390 assembly language is, well, strange to me.

The i370 port is essentially dormant. Almost no one is working on it. This is both good and bad: on the bad side, lots of things don't work. On the good side, you will learn incredible amounts by fixing things. And you will be able to make all of your own decisions, without having anyone to tell you you're wrong. Its a marvelous play-pen.

Below follow some very very brief instructions on how to get started.

Bigfoot, the i370 Port

The following instructions for the i370 port. Download the latest patches from this site.
Get a working Unix box.
You can work on just about any Unix box (e.g. AIX), but you will need a Linux box to create a ramdisk.

Get the latest gcc compiler.
I believe that all of the latest i370 patches are in the latest version of gcc, but I am not sure. Contact me for assistance.

When building gcc, build only the c compiler; you don't need c++ or objective-c or Fortran or Java. Besides, the i370 build always croaked on obj-c. You might run into some nasty error messages ignore them, then build binutils and install binutils. Then rebuild the compiler. I don't know why, but iterating like this should get rid of most error messages.

Build the assembler
Get the latest version of binutils (which is 2.10.1 or something like that). Binutils is the gas assembler, the disassembler, the linker, etc. It really does have all of my latest patches, it just works. The disassembler works too. Again, compile so that it produces i370 code. If you are unclear on the flags you need to specify to do this, then read the docs, and/or pester me. I'll dig out my notes (which I don't have handy here). its something like configure --target=i370-linux; make; or something like that.

Compile the following program: main () { printf ("hello world\n"); } Study the assembly listing. You will eventually become intimately familiar with assembly listings.

The above two steps will take you at least several days.

Build kernel
Get linux-2.2.1 kernel and i370 kernel patches. Use cross compiler to build kernel. Take a look at the Documentation/i370 directory in the kernel source. It has more hints.

Boot Kernel
Boot on the Hercules Emulator, or on VM.
Get the Hercules emulator. Compile & install it. Boot kernel on emulator. I have never done this. Peter Schultz-Stracke has, and can provide help.
Alternately, I will see if my VM account is still good; I might be able to share the passwd with you or get you an account. Have you ever used VM? It has an absolutely marvelous 'hardware' debugger built in, it is excellent and indispensable for debugging. Those poor chumps coding on Intel/PowerPC/alpha have no idea how much better their code, and their life, would be, if they had something like VM and it's debugger.
The kernel should spew the usual boot-sequence messages. The boot will eventually fail because you need a ramdisk containing /bin/sh and other executables. You'll need to prepare one.

Build glibc
Get the glibc source code, and my patches. Apply and compile (using the cross-compiler of course.)

When building glibc, you will need to disable -O2 optimization for some (about a dozen) files. There is something about the way the i370 instruction set is specified that causes a a register allocation overflow (i.e. the compiler core dumps) It is due to some sort of mis-specification of the i370 instruction set, but I wasn't able to quite understand enough to fix it. Write me for details.

Build a shell
Get the very simplest possible shell that you can find (not bash), and cross-compile that.

Build a ramdisk
Do this by getting a linux box, and using the 'loopback block device' to mount a file as if it were a file system. The ramdisk-HOWTO explains how to do this. Create a filesystem. Put the binary for /bin/sh into that filesystem.

Upload. Boot on VM Instructions on booting on VM here.
When you boot that, you will almost get to a command-line prompt before it craps out. And that's where I left it. More about the actual status below.

Technical Status of the i370 Port

The i370 port is quite raw, and all but the very finest coders should stay away. Here's the quickie status report.
Simple output to the screen works. The tty code is sort of broken; There are some practical problems with the 3270 console that makes implementing a console for mainframe Unix 'ugly'. That's OK, in the future, people should telnet in ... Anyway, we never even started getting console input (i.e. the keyboard) to work. My patches are for the 2.2 kernel. However, at some point, you'll want to work with the 2.4 kernel. Unfortunately, the 2.4 kernel reorganizes a whole lotta stuff. I spent a day trying to port to 2.4, and got nowhere fast.

Currently, the system crashes on the way to the command-line prompt. The /bin/sh would crash just as it tried to write to the screen (and/or in malloc ??). I traced this down to a bad relocation in the linker. glibc had marked __internal_malloc as a 'weak' symbol, and the i370 linker miscalculated the address. I later realized that this was a subtle issue involving PIC (position independent code) which I'd gotten wrong (specifically, PIC jump tables, I think). At that point I realized I needed to redesign the i370 subroutine linkage, because what I had wouldn't work for things like dynamically loaded libraries.

Redesigning the subroutine linkage involves some subtle and fascinating mental gymnastics, as you have to optimize performance and register usage while at the same time making sure the result actually works, e.g. making sure that its re-entrant/interruptible.

Everything Else

The IBM s390 Port

The following instructions for the IBM s390 port. Download IBM patches from the IBM Linux for S/390 Project home page.
> ----------
> From:         Martin Schwidefsky[SMTP:schwidefsky@DE.IBM.COM]
> Reply To:     Linux on VM Port
> Sent:         Thursday, December 23, 1999 10:23 AM
> Subject:      Re: IBM 390 and Linux
> The following steps should provide you a cross build environment:
> 1) unpack all source packages
>    tar xfz binutils-2.9.1.tar.gz
>    tar xfz gcc-2.95.1.tar.gz
>    tar xfz glibc-2.1.2.tar.gz
>    cd glibc-2.1.2
>    tar xfz ~/glibc-crypt-2.1.2.tar.gz
>    tar xfz ~/glibc-linuxthreads-2.1.2.tar.gz
>    cd ..
>    tar xfz linux-2.2.13.tar.gz
>    mv linux linux-2.2.13
> 2) apply the patches
>    patch -sp0 < ~/binutils-2.9.1-s390.diff
>    patch -sp0 < ~/gcc-2.95.1-s390.diff
>    patch -sp0 < ~/glibc-2.1.2-s390.diff
>    cd glibc-2.1.2
>    patch -sp0 < ~/glibc-linuxthreads-2.1.2-s390.diff
>    cd ..
>    patch -sp0 < ~/linux-2.2.13-s390.diff
> 3) configure, compile and install the binutils
>    mkdir binutils-build
>    cd binutils-build
>    ../binutils-2.9.1/configure --prefix=/usr/local --target=s390-ibm-linux
> --host=i386-pc-linux-gnu
>    make
>    su  (enter root password)
>    make install
>    exit
>    cd ..
> 4) configure, compile and install the C compiler
>    mkdir gcc-build
>    cd gcc-build
>    ../gcc-2.95.1/configure --prefix=/usr/local --target=s390-ibm-linux
> --host=i386-pc-linux-gnu --enable-languages="c" --with-newlib
>    make  (ignore the compile error in libiberty)
>    su    (enter root password)
>    make install
>    exit
>    cd ..
> 5) configure the kernel
>    cd linux-2.2.13
>    vi Makefile (set "ARCH := s390" and "CROSS_COMPILE=s390-ibm-linux-")
>    make menuconfig
>    cd ..
> 6) copy kernel header files
>    su    (enter root password)
>    cp -ar linux-2.2.13/include/linux /usr/local/s390-ibm-linux/include/linux
>    cp -ar linux-2.2.13/include/asm-s390 /usr/local/s390-ibm-linux/include/asm
>    exit
> 7) configure, compile and install the glibc
>    mkdir glibc-build
>    cd glibc-build
>    ../glibc-2.1.2/configure --prefix=/usr/local/s390-ibm-linux
>           --host=s390-ibm-linux  --build=i386-pc-linux-gnu
>            --enable-add-ons --disable-profile --enable-omitfp
>    make
>    su    (enter root password)
>    make install
>    exit
>    cd ..
> 8) configure, compile and install all needed compilers
>    cd gcc-build
>    rm -fr *
>    ../gcc-2.95.1/configure --prefix=/usr/local --target=s390-ibm-linux
> --host=i386-pc-linux-gnu --enable-languages="c,c++"
>    make
>    su    (enter root password)
>    make install
>    exit
>    cd ..
> MfG,
>    Martin Schwidefsky
> IBM Deutschland Entwicklung GmbH, Schvnaicherstr. 220, D-71032 Bvblingen
> Telefon: 49 - (0)7031 - 16-2247, Internet-Mail:
> Lotus Notes: Martin Schwidefsky/Germany/IBM@IBMDE


How to configure VM to correctly display printable ASCII:
From Rob van der Heij                 Dec 23, 99 02:46:38 am EST
Date:         Thu, 23 Dec 1999 02:46:38 EST
Reply-To: Linux on VM Port 
Subject:      Re: VM requirement

While waiting for DISPLAY and STORE being enhanced (that's beyond my
my reach since I think it is delivered OCO) this program may be of some
use. Use this only when you know what you're doing and you're the only
user on your system! It replaces the translate table at HCPTBLHE with
the ASCII printables in EBCDIC. At least DISPLAY T uses that table...

With the new Dynamic Exit Points of VM/ESA 2.4.0 you should be able to
call an exit to do the translate (based on a flag in your VMDBK) so a
user can select between ASCII and EBCDIC. This is not difficult to do
but it could break existing applications.

/* ZAPASCII EXEC    ZAP CP translate table to display ASCII          */

'PIPE (end \ name ZAPASCII.EXEC:2)',
   '| spec w1 x2d ',
   '| var a'

'PIPE (end \ name ZAPASCII.EXEC:7)',
   '\ xrange 20 7f',                  /* ASCII printable code points */
   '| xlate a2e',
   '| spec 1-* 33',                   /* From x'20'                  */
   '| pad 256',                       /* upto x'ff'                  */
   '| fblock 4',                      /* Make words                  */
   '| spec 1.4 c2x 2',                /* in hex to store             */
   '| join 3 , ,',
   '| spec ,ST H, 1 pad 0 number from' a 'by 16 d2x n.8 ri 1-* n',
   '| cp'

return rc

Last updated Dec 1999 by Linas Vepstas (
Copyright (c) 1999 Linas Vepstas, except the s390 instructions, which are Copyright (c) 1999 Martin Schwidefsky.
All trademarks on this page are property of their respective owners.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included at the URL, the web page titled "GNU Free Documentation License".

Go Back to the Linux/390 Page
Go Back to the Enterprise Linux Page
Go Back to Linas' Home Page