Setting up Debian Etch to an qemulated arm system

The system can be run either with NFS root, or with emulated hard drive (requiring newer QEMU).

The NFS root method

This part is largely based on the excellent article Running Linux for ARM processors under QEMU by Paul Dwerryhouse, some details omitted in the original article are discussed here. I recommend you to read that article before doing anything yourself.


The whole system is built in Debian Etch, but the instruction may work also on other systems. If you don't have access to a one, you can always run the system under VMware Player by getting a ready installed image. You may need to correct the apt sources to point to a repository near your location, update the system, and install needed developments packages.

Note: lines starting with host# are to be executed as root, while lines starting with host$ can be run as a user in the host system. If the line starts with guest, the instruction is executed on the emulated system.

Host setup

Install few needed packages to the system (qemu for the arm system emulation, nfs server for providing filesystem for the emulated system, and debootstrap to do the actual installation.
host# apt-get install qemu nfs-kernel-server debootstrap

Networking for emulator

For the emulated system to have a network access, we need to install VDE (virtual distributed ethernet) providing virtual network switch for the emulated system. Unfortunately there's no package of VDE in Etch, so you'll need to compile and install it yourself. Grab the package of VDE 1.x from Sourceforge, and compile by:
host$ bunzip2 vde-1.x-yy.tar.bz2
host$ tar xvf vde-1.x-yy.tar
host$ cd vde-1.x-yy
host$ ./configure
host$ make
host$ su
host# make install
host# vde_switch -tap tap0 -daemon
host# chmod 777 /tmp/vde.ctl

Configure the emulated interface by adding the following to /etc/network/interfaces

auto tap0
iface tap0 inet static
        vde-switch vde-net

And to allow access to internet, too:
host# echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE

(If your network insterface has some other name than eth2, replace it here.)

Set groups to allow users to use the device:
host# addgroup vde-net
host# chgrp vde-net /dev/net/tun
host# adduser user_name vde-net
Now you may need to log out and back in to apply the group setting.

Then, bring up the interface:
host# ifup tap0

NFS root

Create a directory where the arm nfsroot will reside, e.g.,
host# mkdir /nfs
host# mkdir /nfs/arm

Set up the nfs server by editing /etc/exports
And start the server
host# exportfs -a

Unpacking guest packages

Install the base packages to the root with debootstrap:
host# debootstrap --foreign --arch arm etch /nfs/share/arm
host# cd /nfs/arm
host# cp /etc/passwd etc/passwd
host# cp /etc/shadow etc/shadow
host# cp /etc/group etc/group
host# echo "proc /proc proc defaults 0 0" > etc/fstab
host# echo " / nfs defaults 0 1" >> etc/fstab
host# mknod /nfs/arm/dev/console c 5 1

The debootstrap fetches the defined base packages (etch for arm architecture) and does an initial unpacking of them. However, the system is not runnable, as not all steps could be compilshed due to differring architectures. After unpacking, few setup details are copied or created. (If you omit the last row creating console device, the boot will probably fail.)

Guest system kernel

Get an ARM kernel, e.g., from qemu's site (the arm-test package), and copy it to a new location. This is used to boot the emulated system.
host# mkdir /usr/local/etc/images
host# mv zImage.integrator /usr/local/etc/images/zImage.arm
host# chmod 755 /usr/local/etc/images/zImage.arm

Emulator start-up script

Create a startup script to /usr/local/bin/start-qemu-arm.


console="ttyAMA0"         # serial console
nfsserver=""  # address of NFS server
nfsdir="/nfs/arm"         # exported share where debian/arm is installed
address=""   # address for guest server
gateway=""    # default gateway
netmask=""   # subnet mask
hostname="arm.home"       # hostname for guest server
device="eth0"             # interface that guest server will use
mem=128                   # memory for guest server in Mb
tap="/tmp/vde.ctl"        # vde tap socket

kernel="/usr/local/etc/images/zImage.arm"	# arm kernel
nfsopts="rsize=8192,wsize=8192,hard,intr,tcp,nolock"	# nfs options



if [ "x$1" == "xsingle" ]

vdeq qemu-system-arm -sock $tap -m $mem -kernel $kernel	-append "$consoleopt root=/dev/nfs $nfsrootopt $ipopt $init"

Allow users to execute the script:
host# chmod 755 /usr/local/bin/start-qemu-arm

Finalise the debootstrap process by running the emulated system (will be slow).
host$ /usr/local/bin/start-qemu-arm single

Finalising installation on guest

If everything went fine, the system should be booting now nicely. The emulated guest server should start up and boot into a bash prompt. The filesystem will be mounted read-only, and it will be necessary to remount it read-write before any further work can be done on it:
guest# mount -n -o remount,rw /
guest# mount /proc

Now run the second stage of debootstrap, within the guest system, to finalise the installation: guest# cd /
guest# PATH=$PATH chroot / debootstrap/debootstrap --second-stage
The PATH magic is needes because otherwise the process would fail.

Now you should have a root prompt on the emulated system. It might be a good idea to test that the network is operational, e.g. with ping.
guest# ping -c 2

Post script

That's it! You have an etch debian system running on emulated arm and you can use it e.g. for compiling your software for arm systems. The main downside is that especially with dual emulation (hardware running windows running VMware running host x86 debian running qemu running arm debian) the resulting system is on the slow side. Few tweaks I'd recommend: install ntp to keep system on time to avoid problems with repositories...

The emulated hard drive method

This part will discuss how to install the system without a NFS root to an emulated hard drive. Much of this information is base on the article Debian on an emulated ARM machine by Aurelien Jarno. I suggest you to read that article before doing anything. I had to fight quite a lot to get the system working based on the original article, so I decided to document the required minor details here.

Host setup

The described method is assumes that your host system is Windows. Most of the instructions should still apply with Linux hosts. The qemu needs to be at least version 0.9.0 to support hard drive emulation with ARM systems.

Start by creating an emulated hard drive for the system with:
host# qemu-img create -f raw hda.img 10G
This will create a 10GB disk image using the raw format, i.e., using 10GB space. It is possible to use also compressed formats, such as qcow2, but in my experiments they caused the emulated system to crash.

Networking for the emulator

To enable the emulated system to have a possibility to communicate with the Internet, a virtual network adapter needs to be installed. Download and install OpenVPN. It will add a new adapter to your system. Rename it e.g. to TAP. Configure it to address It seems that the address needs to be just that, at least with Windows. Enable internet connection sharing by selecting your real network adapter -> advanced -> "allow other network users.." -> select the TAP interface. ICS forces the address to, so that was the reason to use it.

Installing the system

Get a kernel for the system from, and the network install ramdisk from a Debian repository

Now you can boot the system with the installer
host# qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.18-4-versatile -initrd initrd.gz -localtime -hda hda.img -append "root=/dev/ram" -net nic -net tap,ifname=TAP
This should boot the Debian installer. Answer the questions and install the system. When the installer complains about the kernel, just continue without installing a kernel. The installation should go almost smoothly, except at least in my case it failed with ispell packages. However, that doesn't seem to be any problem. Finally choose to "continue without a boot loader". After this the system will try to reboot. Stop it before restarting.

Get a new ramdisk from Now restart the system with slightly different command:
host# qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.18-4-versatile -initrd initrd.img-2.6.18-4-versatile -localtime -hda hda.img -append "root=/dev/sda1" -net nic -net tap,ifname=TAP
(At least in Windows, if you don't specify the network on command line, the system will not have any network connectivity.) For some reason, the system may check the root file system twice and reboots before continuing any further.

Finalising the installation

This network setup may not be necessary if the installation was done properly. Edit the file /etc/network/interfaces by adding the following lines

auto eth2
iface eth2 inet static

Now you can enable the emulated system network with:
guest# ifconfig eth2 up
Add your name server addresses to /etc/resolv.conf.
Now you should be able to finalise the installation by running:
guest# apt-get update
apt-get install console-common console-tools ntp initramfs-tools

The first three are to enable different keyboard layout and to keep the system clock correct. Finally get a new kernel for the system:
guest # wget
guest# dpkg -i linux-image-2.6.18-4-versatile_2.6.18.dfsg.1-12+versatile_arm.deb

After rebooting, the system should be all ok for use.

Valid HTML 4.01 Transitional paulus, 2007/08/05