Lately I've been trying to get an x86 emulation environment working on my
powerbook so I can test out the backend of our compiler. Eventually I hope to
write a PPC backend, but in the near future x86 is the only platform it's going
to run on.
The first step was to build a cross-compiling version of gnu bintools for
x86. We're generating assembly code and using gnu as to assemble it, so I
would be needing a version that could generate x86-elf executables. Happily,
this was pretty straightforward:
$ ./configure --target=i586-unknown-linux-gnu --prefix=/usr/local/xcomp -v
$ make all
$ sudo make install
I could now build little-endian x86 binaries from asm programs like the one in
the Linux Assembly
HOWTO.
The next step was to get an x86 emulator. Bochs is the economical, open-source
choice here. There are other commercial emulators like Virtual PC that are much
faster, but I just need to be able to try out tiny compiler test programs –
performance is not important, and money is.
Setting up Bochs wasn't too tough, but their bochs.scpt had a bug in it that
kept it from working. I ended up just running
bochs.app/Contents/MacOS/bochs manually to launch the emulator.
So now I could build Linux x86 binaries and I could run Linux x86 binaries. The
only issue remaining was getting the binaries into the emulator. What I mean is
that the emulator uses a Linux ext2 filesystem inside a disk image as its
virtual hard drive. If I want to run something on the emulator I have to get it
onto that hard drive (or some other drive that the emulator can access).
Unfortunately, OS X doesn't have built-in support for ext2 filesystems.
Fortunately, somebody
else provides it.
So I downloaded ExtFSManager, installed it and rebooted. Unfortunately, I
still couldn't mount the ext2 disk images I wanted to use. When I tried
open hd10meg.img I would get an error complaining that the image
had no mountable filesystems. Under linux I would have tried mounting the image
to a loopback device and then investigating further. After some research I
discovered that the way to do this under OS X is: hdid -nomount
hd10meg.img This mounts the image as a device (e.g. /dev/disk1) without
attempting to mount any of the filesystems on the image.
So now I had hd10meg.img mounted on /dev/disk1. It turns out that I just needed
to fsck a partition on the filesystem to get it to mount correctly with open:
$ sudo fsck_ext2 /dev/disk1s1 # The second partition of disk 1
. . .
$ hdiutil eject /dev/disk1
$ open hd10meg.img # everything works fine now...
Voilla! Now I can mount the disk image and copy files to and from it. Next I'm
hoping to figure out a way to be able to copy files in and out of a running
emulator. It seems that just copying files into the mounted image while the
emulator is running doesn't work. I'll have to set up networking or use virtual
floppies or something. But that's work for another day.