Note: I started writing this article back in 2015 and hit a few roadblocks that I’ve been able to finally reconcile in the last few months. There are a lot of similar guides out there (which I will reference in my sources), but I found them to be too ambiguous to be completely helpful. While I’ve learned a lot from writing this and troubleshooting the issues from existing¬†guides, I am still far from a mainframe expert. There may be errors here, or things I could have accomplished in a better, more “proper” way. That said, I ultimately have a usable z/OS system up and running, and I hope I can help you have the same ūüôā


I recently became aware of the fact that mainframes are still alive and well in the corporate world. But why? Why not just use supercomputers? Mainframes aim to perform a high number of instructions¬†per second, usually measured in the millions. If you hear someone talking about millions of instructions per second (MIPS), they’re probably measuring mainframe throughput. Supercomuters on the other hand aim to have a high number of floating-point operations per second (FLOPS). The difference is that mainframes usually deal with information processing in a short window while supercomuters usually deal with simulations requiring a lot of floating-point arithmetic. A supercomputer might be more suited to weather calculations on Jupiter, but a mainframe is still a better candidate for processing a lot of transactions like you might find in banking or airline booking systems.

Okay, but why not use some sort of content distribution network or cloud computing? For years, mainframes have been touted as the go-to for mission critical processing, with minimal downtime. While cloud computing is catching up in this regard, it can be argued that mainframes are still unrivaled when considering their efficiency and maintainability. One mainframe may be able to process a chunk of data more efficiently than thousands of linked machines in remote locations. Now, consider maintenance. Would you rather update one machine or thousands? And scalability? Many cloud providers supply controls to ramp up power when needed (such as during the holidays) or dial it back during more sleepy periods. Mainframes offer the same sort of control, and can easily scale up or down as needed without someone (or piece of software) needing to roll out or switch off a few hundred more servers.

Mainframes are an interesting piece of technology that still have a purpose, but they rarely discussed these days with the influx of new technologies in processing. It’s easy to try these services out, even for an amateur, but getting your hands on a mainframe is incredibly difficult in comparison. Even if you happened to be employed at a company still utilizing one, you would need training and shadowing sessions before even having the chance to touch a keyboard on a production machine.

Of course, there are ways to explore these systems without needing a physical unit, and that is what I’m going to get into momentarily. It is now possible to get your own taste of Big Iron right from your personal computer.


Before we get into installing Hercules, an IBM mainframe emulator, you are going to need to find an image of z/OS. z/OS is the operating system of choice for modern IBM mainframes, but it is a little hard to get your hands on unless you actually have a full-scale system set up somewhere already. There are images of z/OS floating around the Internet that can be found, specifically version 1.10. I will not be sharing where these files can be found, and if you do find them, make sure you adhere to the software license while running z/OS.

Now, we also need a host system to support the Hercules emulator. While Hercules will run in Linux, Windows, and OSX, this guide will use a machine running Linux, specifically Debina 9 (Stretch). I will assume that you already have a system running Debian (or similar) and a non-root, sudo user with access to the z/OS files.

After all of this is set up, we can begin installation!

Configuring Hercules and c3270

First, we need to install some basic utilities and applications. But, one of them (c3270) is not available right away as it is classified as “non-free” software under Debian. You can still install packages like this, you just need to configure your system to do so. We need to edit the sources.list file to allow non-free packages.

Simply add non-free to the end of the stretch and stretch-updates sources by editing /etc/apt/sources.list with your favorite text editor:

$ sudo nano /etc/apt/sources.list

After editing, it should look like this:

$ cat /etc/apt/sources.list

deb stretch main non-free
deb-src stretch main non-free

deb stretch/updates main
deb-src stretch/updates main

# stretch-updates, previously known as 'volatile'
deb stretch-updates main non-free
deb-src stretch-updates main non-free

Now we are ready to install the packages we need. All of them can be installed by running the following command:

$ sudo apt-get install -y c3270 hercules

As this starts executing, go and put on a pot of coffee. As soon as you turn the machine on and walk back to your computer, this command will probably be through.

The above has installed hercules, our IBM system emulator as well as c3270, a IBM 3270-compatible terminal emulator that we will use to interface with our system.

Now, I’m going to assume you have the z/OS files somewhere on your Linux machine, possibly in a directory path like IBM\ ZOS\ 1.10/Z110SA/images/Z110\ -\ Copy. I will assume that the root IBM folder is in your home directory. We will reorder things by creating a directory MAINFRAME within the home directory to house the z/OS installation:

$ cd ~
$ mv IBM\ ZOS\ 1.10/Z110SA/images/Z110\ -\ Copy ~/MAINFRAME
$ mkdir PRTR

We will now have the following heirarchy:


At this point, we need to edit the config file that Hercules reads to boot our mainframe. You can open up the config file in your favorite text editor and follow along with the lines we will modify:


First, we need to edit lines 38/39/40 of the config to map to your PRTR, CONF, and DASD directories in your ~/MAINFRAME directory. We will be using full directory paths, so use your username in place of mine, famicoman.



Now, we edit networking information on line 115. We will need two unused IP addresses on our local network. We can get our machine’s current IP address using the ip command.

$ ip address show eno1
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether fc:3f:db:09:60:59 brd ff:ff:ff:ff:ff:ff
inet brd scope global dynamic eno1
valid_lft 81093sec preferred_lft 81093sec
inet6 fe80::fe3f:dbff:fe09:6059/64 scope link
valid_lft forever preferred_lft forever

Our Debian machine is located at We can pick two additional addresses in the - range. and are currently unused so these will be chosen. will be something of a virtual gateway for the mainframe (think of this sort of like an address for Hercules itself, which we will use as our entry point) while will be an address for the z/OS machine. Keep in mind that will be exposed to your network independently of your host machine, creating a logically separate machine. This means you can access it with its own address, and create separate firewall rules, port forwarding, etc. as though it was physical machine on your LAN.

We will replace the content at line 115 in the config with the following to create a virtual adapter to handle networking with our chosen addresses:

0E20.2 3088 CTCI /dev/net/tun 1500

Lastly, we edit line 31. This line changes the default port for Hercules console connections (made by c3270) from 23 to something of your choosing. I will be using port 2323 as I may be using port 23 otherwise, and it is not a privileged port.


Now we can launch Hercules! (Do you smell your coffee percolating yet?)

I prefer to use screen sessions to keep thing organized (If you don’t have screen, install it with sudo apt-get install screen or just use tmux). This is also handy with using a virtual or remote host machine as you can keep the sessions going when not connected to the host. The below will place you in a new screen session where we will launch Hercules:

$ screen -S hercules

And now for the launch, specifying the config we edited earlier:


Hercules will begin to load (and give you a lot of logs). Then you will be presented with the Hercules console.

The Hercules console after launching. Note our tun0 device opening and our custom console port specified.

The Hercules console after launching. Note our tun0 device opening and our custom console port specified.

Now, we want to create a 3270 terminal session with Hercules. So, hold + A + D to detach your screen session, returning you to your original console window on the Debian host. Next, create a new screen session for our 3270 connection:

$ screen -S c3270

Now in our new screen session, we will launch c3270 to connect into Hercules, emulating a 3270 connection to actual hardware:

c3270 localhost 2323

You should be presented with a Hercules splash screen:

The Hercules splash screen.

The Hercules splash screen.

Detach from your c3270 screen session and reattach to the hercules session. It might be a good idea to open a new terminal window on the host machine to keep multiple screen sessions open at once. I suggest two terminal windows, one with hercules and one with c3270. To reattach your hercules screen session, use the below command after detaching:

$ screen -r hercules

Now that you are presented with the Hercules console again, you should see your connection from the 3270 session in the logs.

HHCTE009I Client connected to 3270 device 0:0700

Booting z/OS

Now we can boot z/OS for the first time! In the Hercules console, type the following and hit :

ipl a80

z/OS will now boot. Your coffee should be done by now, so go grab a cup. I’ll wait.

Depending on the specs of the host machine, this could take a long, long time. The first boot took around 90 minutes for me, and could take even longer. At this point, you will get a lot of logging info in both the c3270 session and the hercules session. A lot of this looks like it could be reporting that something has gone horribly wrong, but don’t worry, it is likely okay. This is probably a good time to go for a walk outside with your coffee. Maybe take a good book and settle under a tree for a bit.

A Potential Boot Issue

I did run into the following message on my c3270 session at some point while attempting boot:


If this happens to you, you can safely type the following in the c3270 session and hit :

R 00,I

This will allow z/OS to continue booting.

This message in the 3270 console halted boot-up. Entering the provided command can resume system startup.

This message in the 3270 console halted boot-up. Entering the provided command can resume system startup.

If you are unsure whether or not z/OS is fully booted (It can be hard to tell), the easiest thing to do is open another c3270 connection to localhost (maybe create a new screen¬†session via screen -S terminal). If you get the Hercules splash screen again you can safely close the session ( + ], then type “exit”), wait a little longer, and try connecting again. Eventually, your second terminal session should connect and get to the log-on screen for your z/OS installation.

Welcome to the DUZA system!

Welcome to the DUZA system!

To log in, we enter “TSO” at the prompt. When prompted for a username, enter “IBMUSER”.

Login starts by asking for a USERID.

Login starts by asking for a USERID.

Then, enter “SYS1” as the password.

The password gets blanked out as you type it.

The password gets blanked out as you type it.

From here, press , then the ISPF menu will launch.

You will get some brief messages after logging in. Press the key to go to the ISPF menu.

You will get some brief messages after logging in. Press the key to go to the ISPF menu.

The ISPF menu serves as a gateway to a lot of system functionality.

The ISPF menu serves as a gateway to a lot of system functionality.

Now in the ISPF menu, type “3.4” to load the Data Set List Utility.

Replace “IBMUSER” in the “Dsname Level” field with “DUZA” and press .

We will use the Data Set List Utility to locate our network settings.

We will use the Data Set List Utility to locate our network settings.

Scroll down using the key in the Data Sets list and locate the one called DUZA.TCPPARAMS. With your cursor, click on the ‘D’ in “DUZA.TCPARAMS” and use the left-arrow key to navigate three spaces to the left. Type the letter ‘E’ and hit to see items in this data set.

We need to edit the TCPPARAMS for the DUZA system.

We need to edit the TCPPARAMS for the DUZA system.

On the next screen, use your cursor to click on the first position on the line to the left of the word “PROFILE”. Type the letter ‘E’ and hit to edit this item.

Finally, we can edit the Profile.

Finally, we can edit the Profile.

Use to page down to line 90:

000090 DEVICE LCS1 LCS E20
000093 HOME
000094 ETH1
000096 GATEWAY
000097 = ETH1 1500 HOST
000099 DEFAULTNET ETH1 1500 0
000109 START LCS1

Modify the lines so they look like the following with our IP addresses outlined earlier (and don’t forget line 109!):

000090 DEVICE CTCA1 CTC e20
000091 LINK CTC1 CTC 1 CTCA1
000093 HOME
000094 CTC1
000096 GATEWAY
000097 = CTC1 1492 HOST
000099 DEFAULTNET CTC1 1492 0
000109 START CTCA1

To save the updated config, place your cursor to the first underline character to the right of “Command ===>” and type “SAVE” followed by the key. Next, type “END” at the same location, again pressing the key.

Here is what the updated settings look like via the 3270 terminal:

Our updated networking is ready to save. Note the IP addresses we specified earlier when configuring Hercules.

Our updated networking is ready to save. Note the IP addresses we specified earlier when configuring Hercules.

Next, we need to recycle the TCPIP service on the system. Go back to your first c3270 console session (detaching your terminal¬†session) and type¬†“STOP TCPIP” followed by the key in the console.



Wait a minute or two and then type “START TCPIP” followed by the key. After both commands, you should see a lot of console output regarding the TCPIP service. After starting the service back up, wait a few minutes before proceeding to make sure everything has come back up.

After running START TCPIP.

After running START TCPIP.

After restarting the TCP service, we need to detach the session and do a few more things on our host machine.

Back on the Debian host machine we need to enable IPv4 forwarding and proxy arp with the following two commands to get networking sorted out:

$ sudo sh -c "echo '1' > /proc/sys/net/ipv4/conf/all/proxy_arp"
$ sudo sh -c "echo '1' > /proc/sys/net/ipv4/conf/all/forwarding"

Testing Networking

We can now test whether we can remote into our z/OS machine, and if we can get out from the inside. From the console on the host Debian machine, telnet to our mainframe using port 1023:

$ telnet 1023

Login with the credentials we used earlier (IBMUSER/SYS1) and try out a traceroute command:

Connected to
Escape character is '^]'.
Licensed Material - Property of IBM
5694-A01 Copyright IBM Corp. 1993, 2008
(C) Copyright Mortice Kern Systems, Inc., 1985, 1996.
(C) Copyright Software Development Group, University of Waterloo, 1989.

All Rights Reserved.

U.S. Government Users Restricted Rights -
Use,duplication or disclosure restricted by
GSA ADP Schedule Contract with IBM Corp.

IBM is a registered trademark of the IBM Corp.

IBMUSER:/u/ibmuser: >traceroute
CS V1R10: Traceroute to (
Enter ESC character plus C or c to interrupt
1 (  1 ms  1 ms  1 ms
2 (  70 ms  4 ms  3 ms
3 (  5 ms  6 ms  4 ms
4 (  10 ms (  8 ms (  10 ms
5 * * *
6 * * *
7 (  10 ms (  9 ms (  6 ms
8 (  16 ms  11 ms  11 ms
9 (  12 ms (  12 ms (  10 ms
10 (  10 ms (  15 ms (  12 ms
11 (  11 ms  19 ms  10 ms

You can additionally try out some more Unix commands:

IBMUSER:/u/ibmuser: >uptime
07:55PM  up 6 day(s), 03:54,  1 users,  load average: 0.00, 0.00, 0.00
IBMUSER:/u/ibmuser: >uname -a
OS/390 DUZA 20.00 03 7060
IBMUSER:/u/ibmuser: >whoami
IBMUSER:/u/ibmuser: >ls
CEEDUMP.20050812.162501.65568  ptest.c                        setup1
SimpleCopy.class               ptest.o                        setup2                ptestc                         setup3
hfsin                          ptestc.trc.16842781            zfs
hfsout                         setup

Back in your second 3270 connection (which like me you may have named terminal), you can keep entering"EXIT" in the “Command ===>” field until you return back to the ISPF menu we saw earlier.

There are many options from the ISPF menu. Take some time to explore them when you get a chance!

There are many options from the ISPF menu. Take some time to explore them when you get a chance!

From here, you can enter “6” in the “Option ===>” field to get to the Command menu. From here, you can try out other various commands like ping¬†or netstat by¬†entering them into the “===>” field.

Here is the output of netstat. Notice how previously used commands are cached for you.

Here is the output of netstat. Notice how previously used commands are cached for you.

Shutting it Down

You always want to make sure to shut down your mainframe in the proper way. Otherwise, you may end up with corrupted data or an unbootable system!

From your first c3270 session, enter in¬†“S SHUTSYS”.


Then after a little while enter in “Z EOD”.

Starting the shutdown process.

Starting the shutdown process.

After a few minutes the machine will halt. Then, switch over to your Hercules console and enter in “exit” to close out Hercules.


Rebooting the mainframe follows the same start-up process from initial boot, so you can easily come back to things.


That’s it, you now have a functioning mainframe! Albeit, it will be much slower than a real mainframe on real hardware (emulation on my machine usually only clocks between 5-12 MIPS).

Toggle back and forth between the console and graphical view in Hercules with the key.

Toggle back and forth between the console and graphical view in Hercules with the key.

Feel free to explore the system, and start learning how to use z/OS and customize your installation!