QEMU: MiraBox Emulation
As I mentioned in a previous post, I host various websites (including this one) on a MiraBox sitting behind my tv. In that same post I outlined how Globalscale screwed me by mixing releases in the sources.list. I didn't catch it until I had an unbootable system, and I had to completely rebuild my server which took weeks. I very nearly tossed the whole thing in favor of hosting my websites on a "real computer, made by people who knew what they were doing," but I reminded myself why I settled on the MiraBox in the first place: I like embedded stuff. I'm a computer engineer, this is what I find interesting. Is installing new things on this box harder than on an x86? Sure. But do you learn new things every time you play with it? Definitely.
So, I rebuilt my server on the MiraBox again. And now it's working better than ever (now that I've fixed my sources.list). However, I also have an Owncloud install on here, which I recently tried to upgrade. Of course, I broke it and had to spend a few days rolling back (something weird happens to a PostgreSQL database when you update Owncloud 4.8 to 5... I haven't figured it out yet). Some of you might be laughing, because I STILL hadn't learned my lesson: You don't do research and development on production systems. You get it working in a parallel environment, and then deploy it. I've got it now, I promise. However, there's no way I'm shelling out for another MiraBox just to play the role of a staging server, so I've come up with another idea: using QEMU to emulate the MiraBox environment as closely as possible.
QEMU is a simple, open-source machine emulator. When I decided to go the virtualization route, my first thought was obviously VirtualBox, but a quick google revealed that it doesn't support other architectures. So after some research, I settled on QEMU for ARM emulation.
My MiraBox server is running Debian Squeeze, so the first step is to download Debian Squeeze to install on the emulated staging server. However, installing on an ARM is a bit different than installing on, say, an x86. Instead of using the .iso, you need to seperately download the ARMEL kernel image and installer.
$ mkdir -p ~/qemu/debian/squeeze
$ mkdir -p ~/qemu/images
$ cd ~/qemu/debian/squeeze
$ wget http://ftp.debian.org/debian/dists/squeeze/main/installer-armel/current/images/versatile/netboot/initrd.gz
$ wget http://ftp.debian.org/debian/dists/squeeze/main/installer-armel/current/images/versatile/netboot/vmlinuz-2.6.32-5-versatile
Now an image needs to be created for the VM. I like the QEMU's copy-on-write strategy, so I use the qcow2 format. I also have Debian on a 32 GB SD card inside the MiraBox, so I'm making this image 32 GB.
$ qemu-img create -f qcow2 server.img 32G
Formatting 'server.rainveiltech.com.img', fmt=qcow2 size=34359738368 encryption=off cluster_size=65536 lazy_refcounts=off
Now it's time to actually install Debian. I was really hoping for a way to emulate the MiraBox hardware as closely as possible, but it seems that the closest I can get with QEMU is the arm5 instruction set (the MiraBox can use arm7). I figured that would be good enough, so I walked through installing Debian:
$ qemu-system-arm -M versatilepb -kernel ../debian/squeeze/vmlinuz-2.6.32-5-versatile -hda server.rainveiltech.com.img -initrd ../debian/squeeze/initrd.gz -append "root=/dev/ram" -m 1G
After it had finished installing, I fired it up to make sure everything looked good:
$ qemu-system-arm -M versatilepb -kernel ../debian/squeeze/vmlinuz-2.6.32-5-versatile -hda server.rainveiltech.com.img -initrd ../kernels/initrd.img-2.6.32-5-versatile -append "root=/dev/sda1" -m 1G
It looked fine, but by default the user-mode networking stack won't allow any incoming traffic (reference) so I decided to just forward port 80 on my host machine to the guest machine, with -redir tcp:<host port>::<guest port> or in my case:
$ qemu-system-arm -M versatilepb -kernel ../debian/squeeze/vmlinuz-2.6.32-5-versatile -hda server.rainveiltech.com.img -initrd ../kernels/initrd.img-2.6.32-5-versatile -append "root=/dev/sda1" -m 1G -redir tcp:80::80
Now I can install Apache etc. and test out new settings! I was having some trouble getting Gitlab setup on the MiraBox, so now I can play with it here instead of my production system.
I still wish I could get Debian running on an emulated arm7 system. If anyone knows how to do that, please share!