Bochs: A Portable PC Emulator For Unix/X

A software solution that allows you to run PC programs ona SPARC station.
A Technical Look at Bochs

Since the term “emulator” has been tossed around quite a bit in recent times, let me clarify the different types of emulation. Software such as DOSEMU and Wine are, in my terminology, environmental or OS emulators. That is, they run the executables natively (x86 code running on an x86 processor) and translate or “emulate” the interaction between the OS the executable expects (like MS Windows) and the OS that is currently running (like Linux). This kind of “emulation” is bound to an x86 platform, since no instruction set emulation is provided, but it is very efficient and an excellent alternative to having a dual-boot setup on your x86 machine.

Bochs is a pure emulator in that it emulates each x86 instruction in software, along with the necessary BIOS and hardware you expect to find on a PC. There's one giant decode loop, which closely models the fetch-decode-execute actions of the CPU. Components of the CPU—namely the registers—are modeled by fields in a large structure representing the CPU. Main memory is represented by a large array of memory within the C program. Input and output devices, such as the keyboard, timers, PIC, etc., are of a very modular design, “plugging into” the rest of the code via the registration of their corresponding IRQ, I/O address space usage, and interrupt service routines.

Bochs needed to emulate a graphics card supported by Windows, and I chose the monochrome Hercules Graphics Adapter (HGA), since it was the simplest to implement. Using an X window to represent the PC monitor and video frame buffer was a portable and natural choice, and it provided a keyboard input mechanism, as well.

Since all instructions are emulated in the C language, Bochs is not bound to any particular processor and is very portable to many other Unix platforms. I want to extend this theme as far as possible, and would like to see Bochs ported to other non Unix-like OSs, like Mac OS.

As with any emulation software, performance is always an issue, as running programs under an emulator is inherently slower than running native software. I've tried to keep performance in mind while coding Bochs, though I am postponing some optimizations until later, so that they don't interfere with the development path towards 386 emulation.

A few people have asked me if I had any plans for adding dynamic compilation techniques to Bochs to enhance the performance. I strongly subscribe to the K.I.S.S. philosophy, and I'd like to keep the source simple, understandable, and manageable, so I doubt I will add it any time soon. There is room in the immediate future for some more traditional performance enhancements, however. I think flags processing is an area with potential performance improvements. Though, one of the blessings of using such a simplistic (and brute-force) method of emulation, devoid of many fancy optimizations, is there are no problems handling self-modifying code, since the instruction stream is decoded and executed on-the-fly.

From the beginning, I coded Bochs to be a 32-bit emulator (386 and up). Internally, registers and other features have always been represented by 32-bit quantities. This has been an immense help, as I continue to add 32-bit processor features to the emulation support.

Compiling and Installing Bochs

Since I began use of the GNU “autoconf” utility, the configuration and compilation process has become much easier and more portable. However, the process of setting up the environment (hard disk and floppy image files, VGA font, etc.) and the installation of DOS/Windows 3.1 within Bochs is a little lengthier. Consult the INSTALL file within the Bochs distribution for details. However, to give you a feel for the compilation and configuration process, I'm including the commands I use to compile Bochs and install Windows 3.1 on my Linux machine. Note, I'm using tcsh, and commands may vary on different platforms.

First, unpack the distribution:

$ cd parent-dir
$ gzip -dc bochs-YYMMDD.tgz | tar xvf -

Then configure the Makefile and source code, and compile.

$ cd bochs-YYMMDD
$ setenv CFLAGS "-O3 -Wall -m486"
$ ./configure --enable-80286 \\
  --enable-native-floppy
$ make

If you are using a Bourne shell, such as bash, setenv will not work. Use

$ CFLAGS="-O3 -Wall -m486"; export CFLAGS

instead.

You may need to install the “VGA” font. Read the INSTALL file within the bochs distribution for this procedure. Your font directory may be /usr/lib/X11/fonts/misc, /usr/openwin/lib/X11/fonts/misc, or somewhere else.

$ cp fonts/vga.pcf font-dir
$ mkfontdir font-dir

Create a bootable 1.44M floppy containing the DOS FORMAT and FDISK executables, using a real DOS machine. Assuming the 1.44MB floppy is drive A:

C:> FORMAT /s /u A:
C:> COPY FORMAT.COM A:
C:> COPY FDISK.EXE A:

Now insert this floppy into your workstation, and create an image of it as a Unix file. Assuming your 1.44MB floppy drive is /dev/fd0, do this:

$ dd if=/dev/fd0 ibs=512 of=1.44

Create an empty 1.2M floppy image file for B: (unused in this example):

$ dd if=/dev/zero of=1.2 bs=512 count=2400

Now create a 20MB hard disk image file (other sizes are possible, but we'll stick with a simple example for now):

$ dd if=/dev/zero of=20M bs=512 count=41820

Edit the .bochsrc file included at the top level of the source. Change the floppya line to floppya: file=./1.44, change the floppyb line to floppyb: file=./1.2, and change the diskc line to diskc: file=./20M.

Boot Bochs with the 1.44M floppy image file:

$ bochs -bootA

Bochs should now be running. Press the Return key a couple of times and accept the date and time.

Use FDISK to partition the C: drive (the 20M file). Add the whole drive as a PRIMARY partition. That is, run FDISK, and type Return three times; once to “Create DOS partition or Logical DOS Drive”, once to “Create Primary DOS Partition”, and once to chose the maximum size.

At this point, just click a mouse button on the window to exit bochs. Since Bochs doesn't support rebooting yet, you must exit and restart Bochs, then format the C: drive and add the DOS system files to it:

$ bochs -bootA
A> FORMAT /u /s c:

Again, quit Bochs by clicking any mouse button in the window.

Now change the floppya line in .bochsrc to floppya: 1_44=/dev/fd0. Put Disk 1 of the Windows 3.1 installation set in the floppy drive. Then restart Bochs, booting from the hard drive image file, and fire up the Windows 3.1 installation:

$ bochs -bootC
C> a:setup

Press the Enter key to install Windows now, and press. “c” to do a custom installation. Press Enter again to install Windows in the default C:\WINDOWS location.

In the Windows Setup screen, everything should be recognized fine, except the keyboard type, which you will need to change. Use the arrow keys to select “All AT keyboards”. Continue installing Windows, using keystrokes only (remember, clicking the mouse in the window exits Bochs). There is no point in setting up printers and applications. Allow Windows to create (or change) your AUTOEXEC.BAT and CONFIG.SYS files, and watch Windows boot. Then return to DOS, click in the window to exit Bochs, and restart Bochs and Windows:

$ bochs -bootC
C> WIN

Figure 1 shows a sample screen. Note that there are some artifacts of bugs in the display code showing.

______________________

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState