The system can be run either with NFS root, or with emulated hard drive (requiring newer QEMU).
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.
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
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# 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 address 192.168.20.1 netmask 255.255.255.0 network 192.168.20.0 broadcast 192.168.20.255 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
Now you may need to log out and back in to apply the group setting.
host# chgrp vde-net /dev/net/tun
host# adduser user_name vde-net
Then, bring up the interface:
host# ifup tap0
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
Install the base packages to the root with debootstrap:
host# debootstrap --foreign --arch arm etch /nfs/share/arm http://ftp.debian.org/debian
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 "192.168.20.1:/nfs/arm / 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.)
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
Create a startup script to /usr/local/bin/start-qemu-arm.
#!/bin/sh console="ttyAMA0" # serial console nfsserver="192.168.20.1" # address of NFS server nfsdir="/nfs/arm" # exported share where debian/arm is installed address="192.168.20.50" # address for guest server gateway="192.168.20.1" # default gateway netmask="255.255.255.0" # 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 consoleopt="console=$console" nfsrootopt="nfsroot=$nfsserver:$nfsdir,$nfsopts" ipopt="ip=$address::$gateway:$netmask:$hostname:$device" init="" if [ "x$1" == "xsingle" ] then init="init=/bin/bash" fi 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
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 /
The PATH magic is needes because otherwise the process would fail.
guest# PATH=$PATH chroot / debootstrap/debootstrap --second-stage
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 www.debian.org
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...
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.
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.
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 192.168.0.1/255.255.255.0. 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 192.168.0.1, so that was the reason to use it.
Get a kernel for the system from http://people.debian.org/~aurel32/arm-versatile/vmlinuz-2.6.18-4-versatile, and the network install ramdisk from a Debian repository http://ftp.de.debian.org/debian/dists/etch/main/installer-arm/current/images/rpc/netboot/initrd.gz.
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 http://people.debian.org/~aurel32/arm-versatile/initrd.img-2.6.18-4-versatile. 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.
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 address 192.168.0.10 netmask 255.255.255.0 gateway 192.168.0.1
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 http://people.debian.org/~aurel32/arm-versatile/linux-image-2.6.18-4-versatile_2.6.18.dfsg.1-12+versatile_arm.deb
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.