Virtual ARM Linux environment

Our volunteers haven't translated this article into বাংলা (বাংলাদেশ) yet. Join us and help get the job done!

Testing with Linux on ARM architecture using QEMU

This page describes how to get a virtual ARM environment with QEMU that runs (Ubuntu) Linux. This should be useful for anyone who needs to test ARM-specific code and does not have (or necessarily need) real ARM hardware for testing.


This manual assumes that the host system you are using is Ubuntu Linux as well because that makes it easy for us to install the required software from external repositories.

Target board/CPU

QEMU supports multiple boards and CPUs. Of all that I tested, I was only able to get the Versatile Express board to work with more than 256 MB of RAM which is why we are going to use this board. For the target CPU, I tested with Cortex A9 only (ARMv7).

Installing the right software

# Add Linaro's repository, containing their tools and more recent 
# versions of qemu (you need at least qemu 0.15*). 
sudo add-apt-repository ppa:linaro-maintainers/tools 
# Install linaro tools and qemu 
sudo apt-get install linaro-image-tools qemu-user-static qemu-system

# If you want to be able to cross-compile on the host, install these as well
sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueab

Download a Linaro release and hardware pack

You can find suitable release and hardware pack tarballs on the linaro release page. Some of them might work, others might not. I used the two links below that worked fine for me.


Creating the image

''(The following steps we're borrowed from and slightly modified).'' Using the Linaro tools, you can easily create an SD card image from the downloaded packs (this will take a while):

linaro-media-create --image_file vexpress.img --dev vexpress \ 
  --binary linaro-natty-nano-tar-20110302-0.tar.gz \ 
  --hwpack hwpack_linaro-vexpress_20110302-0_armel_supported.tar.gz

Extracting the kernel and initrd

The created image also contains kernel and initrd of our machine. We need those two files outside the image though. The following command mounts the image to "/mnt/tmp":

sudo mount -o loop,offset="$(file vexpress.img | awk 'BEGIN { RS=";"; } /partition 2/ { print $7*512; }')" \
  -t auto vexpress.img /mnt/tmp

Now copy the kernel and initrd files to the current directory (NOTE: Filenames could differ in your build!):

cp /mnt/tmp/vmlinuz-2.6.38-1000-linaro-vexpress . 
cp /mnt/tmp/initrd.img-2.6.38-1000-linaro-vexpress . 
# Create some symlinks for simplicity 
ln -s vmlinuz-2.6.38-1000-linaro-vexpress vmlinuz 
ln -s initrd.img-2.6.38-1000-linaro-vexpress initrd.img

Starting QEMU

You can start QEMU now with the following command:

qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -kernel ./vmlinuz \ 
  -initrd ./initrd.img -redir tcp:2200::22 -m 512 \ 
  -append "root=/dev/mmcblk0p2 vga=normal mem=512M devtmpfs.mount=0 rw" \ 
  -drive file=vexpress.img,if=sd,cache=writeback 

Some explanation of the non-obvious options:

  • The ''-redir tcp:2200::22'' redirects TCP traffic on the host port 2200 to the guest machine (QEMU) port 22. This will allow us to SSH into the machine later by connecting to localhost on port 2200.
  • The ''-m 512'' specifies that we want 512 MB of RAM. You can adjust this, but make sure you also change it in the ''-append'' string.
  • The ''-drive file=vexpress.img,if=sd,cache=writeback'' attaches our images as an SD card. I was told by Linaro people that this way provides faster I/O compared to the traditional ''-sd'' option.

After starting the machine, you should end up with a Linux shell in the QEMU window after some startup time.

Using SSH

To use SSH, you first need to bring up network and install the SSH server package. Bring up network temporarily using the following commands:

ifconfig eth0 up
dhclient eth0 

Now try to install SSH:

apt-get install openssh-server 

To make the network changes permanent, edit the file ''/etc/network/interfaces'' (e.g. with ''vi'') and add the following lines:

auto eth0 
iface eth0 inet dhcp 

Finally, set a password for root using the ''passwd'' command. Now reboot the machine and see if you are able to SSH into it using ''ssh -p2200 root@localhost'' on the host machine.

Document Tags and Contributors

Contributors to this page: decoder
Last updated by: decoder,