Sunday 9 June 2013

How to set up an ARM VM for Open Security Training's "Intro to ARM" course

Don't you hate it when you can't follow the video and end up just staring at the slides?

Folks at published a great course about ARM assembly. Chances are, if you are watching the course, you'll want to follow along with the class' labs and examples. The speaker uses a QEMU VM, which, alas, is not provided with the course. In fact, he uses a QEMU VM inside an Ubuntu VM inside, umm, Windows something? (If you read Russian, check this out :)

Not to worry, thanks to Linaro, it's quite easy to set one up without getting involved into a complex cross-compiling project.

Here's a compressed version how to do it. This works on Macs and Linux-es (or is it Linuces?). None of this is original, I took the info off a bunch of web pages, links below.

ARM VM setup

1. Install QEMU.

sudo apt-get install qemu qemu-system (on Linux)
brew install qemu (on Mac)

You may need to install other packages, depending on what OS you're on, different Linux flavours package QEMU differently. Check that you have qemu-system-arm command on your system, if not:

apt-cache search qemu-system-arm

to see what other packages you're missing. Another utility "qemu-img" will come in handy later, check that it is present as well. Check that your QEMU is at least v1.0 - Debian, for example, has very old builds by default.

2. Now you're ready to get a Linaro image running. Here are slightly modified instructions from Versatile Express is a good choice of a modern ARM system to emulate since form Mac's and Linux' QEMU can do it.

Get image:
gunzip vexpress-a9-nano.img.gz

Extract kernel and initrd:

(IMG=vexpress.img ; if [ -e "$IMG" ] ; then sudo mount -o loop,offset="$(file "$IMG" | awk 'BEGIN { RS=";"; } /partition 2/ { print $7*512; }')" -t auto "$IMG" /mnt/mnt; else echo "$IMG not found"; fi )

sudo cp -vr /mnt/mnt/boot .
sudo chown -R youruser:youruser boot
sudo umount /mnt/mnt

You end up with a number of images in .boot:


Copy the original vexpress image, vmlinuz.* and initrd.* somewhere where you want to keep your VM.

Run image:

qemu-system-arm -kernel vmlinuz-3.3.0-1800-linaro-lt-vexpress-a9 -M vexpress-a9 -cpu cortex-a9 -serial stdio -m 1024 -initrd initrd.img-3.3.0-1800-linaro-lt-vexpress-a9 -append 'root=/dev/mmcblk0p2 rw mem=1024M raid=noautodetect console=tty1 rootwait vmalloc=256MB devtmpfs.mount=0' -redir tcp:5022::22 -sd vexpress.img

This should bring up a black window with a Linux penguin in the top left corner and a usual boot sequence.

3. The image is configured with root autologin, there is a "linaro" user with "linaro" password as well. If you wish to autologins kill "/etc/init/openvt.conf" and edit "/etc/default/autogetty" to disable any autologin.

The qemu command above also maps the VM's port 22 to localhost:5022 so that you can use scp to copy files after sshd is installed like this:

scp -P 5522 projects.tar.gz linaro@localhost:~

4. Install tools inside the image:

apt-get install aptitude
aptitude install binutils gcc gdb build-essential vim openssh-server

...and whatever else looks missing. Beware that the linaro image comes with little free disk space.

apt-get clean

might save you a few megabytes, alternatively see next point.

5. Optional - upsize the image (make a copy first just in case):

qemu-img resize vexpress.img +512M

Then use parted or gparted (not available on Mac, unfortunately) on the image to actually resize the file system. It looks like gparted gets confused (those GUI tools!) - check out for how to deal with it.

Mac users might want to copy the .img file to a linux box/VM and run parted there. There is probably a contrived way using fdisk and resize2fs

6. Even more optional and probably does not work:

apt-get install cpufrequtils

- might speed the VM up a litte. Or it might not, I am not sure this util even works in a VM environment.

Tips and errata for the course

  1. Lab 3 Interrupts is not in the projects.tar.gz :( Day 2 Part 2 video talks about it at length, though.
  2. There are answers inside ".solutions" directory
  3. Day 2 Part 1 around 41:30 (slide 159) is incorrect (I think) about the meaning of the caret in
    LDMFD sp!, {r0-r12,lr}
    it means that the user mode registers are loaded and not the banked registers