Raspberry Pi: Virtualise RPi Debian Squeeze image

The Raspberry Pi is an ultra-low-cost credit-card sized Linux computer which was conceived with the primary goal of teaching computer programming to children. It was developed by the Raspberry Pi Foundation, which is a UK registered charity. The foundation exists to promote the study of computer science and related topics, especially at school level, and to put the fun back into learning computing. Demand for the Raspberry Pi has been incredible due to the huge interest there's a freeze and backlog of orders. In the mean time here's how you can play and get up to speed with the Raspberry Pi Debian distro virtually whilst you wait for your Raspberry Pi to arrive.

The Raspberry Pi is based on the ARM11 CPU architecture and make user of a 700 MHz ARM1176JZF-S core. The Raspberry Pi ARM hardware can be emulated under QEMU to allow virtualisation of (and a chance to play with) the Raspberry Pi distributions. There are currently several Linux distributions that have been ported for the ARM architecture and that are available for the Raspberry Pi. This post focuses on the current Raspberry Pi recommended Debian distro.

Install QEMU

QEMU stands for "Quick EMUlator" and is a processor emulator that achieves a reasonable speed while being easy to port to new host CPU architectures. It also provides an accelerated mode for supporting a mixture of binary translation (for kernel code) and native execution (for user code). QEMU can also be used purely for CPU emulation for user level processes, allowing applications compiled for one architecture to be run on another.

QEMU is used rather than Virtualbox since Virtualbox only virtualise x86 hardware whilst QEMU can emulate the ARM chipset.

# Update your package manager
sudo apt-get update

# Install QEMU
sudo apt-get install -y qemu-kvm kvm-pxe

# Make a working folder for the RaspberyPI files for QEMU
mkdir ~/Qemu-arm && cd ~/Qemu-arm

Download the Debian kernel
The kernel (from German Kern, nucleus, core) is the main component of most computer operating systems; it is a bridge between applications and the actual data processing done at the hardware level. The kernel's responsibilities include managing the system's resources (the communication between hardware and software components). Traditionally, UNIX platforms called the kernel image /unix. With the development of virtual memory, kernels that supported this feature were given the vm- prefix to differentiate them. vmlinux is a file that contains the Linux kernel, the name vmlinux is a mutation of vmunix, while in vmlinuz the letter z at the end denotes that it is compressed (zipped).

# Download the Debian Squeeze kernel
wget ftp://ftp.debian.org/debian/dists/squeeze/main/installer-armel/20110106+squeeze4/images/versatile/netboot/vmlinuz-2.6.32-5-versatile

Download the Debian initial ramdisk
The boot process in Debian is a two-stage process, involving the initial RAM disk (initrd for short). The initrd is a scheme for loading a temporary file system into memory in the boot process of the Linux kernel. First, the bootloader loads the kernel and initrd into memory, and passes the execution control to the kernel. After basic initialization the kernel mounts initrd as a temporary root filesystem. The initrd normally contains the kernel modules and userspace programs, required to initialize the physical or logical device(s) containing the real root filesystem. The initial ram disk contains the drivers needed for the ARM based kernel since the Debian kernel used here does not include all the necessary kernel modules (drivers) e.g. ext4 support and ethernet drivers. After such modules are loaded and neccessary initialization steps performed, initrd mounts the real root filesystem and passes control to the /sbin/init program on it.

Two major goals are achieved with such setup: the kernel size is kept under control by allowing most of the drivers to be compiled as modules (in a initrd-less setup the drivers neccessary for the boot-time initialization of the root device must be compiled into it) and allow the setups which require initialization which cannot be done in-kernel, but is performed by userspace utilities.

# Make a working folder for the initial ramdisk that contains the filesystem
mkdir ./installer && cd ./installer

# Download the initial ramdisk
wget ftp://ftp.debian.org/debian/dists/squeeze/main/installer-armel/20110106+squeeze4/images/versatile/netboot/initrd.gz

# Unzip the ramdisk for Qemu to access
gunzip initrd.gz

Download the Raspberry Pi Linux distribution
Raspberry Pi provides SD card images for various Linux distributions. For each distribution, they provide both a direct HTTP download, a torrent file and a SHA-1 hash; the total number of concurrent direct downloads is limited, so they encourage you to use the torrent file if at all possible. I am going to use the Debian Squeeze Raspberry Pi distribution.

# Move back to the main Qemu-arm folder
cd ..

# Download the Debian Raspberry Pi distribution

Verify the Raspberry Pi Linux zip
Check the SHA-1 checksum to the one below for the debian6-19-04-2012.zip
SHA-1 Checksum: 1852df83a11ee7083ca0e5f3fb41f93ecc59b1c8

# Generate the SHA-1 of the zip file
sha1sum debian6-19-04-2012.zip

# Unzip and extract the image
unzip debian6-19-04-2012.zip

Boot the Raspberry Pi distribution for installation
# Launch QEMU for the first time to install the RaspberryPi distribution

qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.32-5-versatile -initrd ./installer/initrd.gz -hda ./debian6-19-04-2012/debian6-19-04-2012.img -append "root=/dev/sda1" -m 256

A break down of the command and parameters:
qemu-system-arm : the full QEMU system emulator for ARM
-M versatilepb : use the Versatile/PB machine platform
-kernel vmlinuz-2.6.32-5-versatile : the Debian squeeze kernel
-initrd ./installer/initrd.gz : the Debian squeeze initial ram disk
-hda ./debian6-19-04-2012/debian6-19-04-2012.img : use the Raspberry Pi image as the virtual hard disk
-append "root=/dev/sda1" : pass in to the kernel command line the root filesystem is at sda1
-m 256 : set the virtual machine memory to 256mb

Complete the Raspberry Pi Debian installation process
  1. Select a language =  <your choice>
  2. Select a location =  <your choice>
  3. Select a keyboard layout =  <your choice>
  4. Configure the network, Hostname = e.g. RaspberryPi
  5. Configure the network, Domain Name = <blank>
  6. Choose a mirror of the Debian archive =  <your choice>
  7. Choose a mirror of the Debian archive, Mirror = any
  8. Choose a mirror of the Debian archive, Http proxy = <blank>
  9. Set up users and passwords, Root password = <your choice>
  10. Set up users and passwords, Full name for the new user = <your choice>
  11. Set up users and passwords, Username for your account = <your choice>
  12. Set up users and passwords, Username password = <your choice>
  13. Partition disks, Partitioning method = Guided - use entire disk
  14. Partition disks, Select disk to partition = SCSI1 (0,0,0) (sda)
  15. Selected for partitioning, Partitioning scheme = All files in one partition
  16. Partition disks = Finish partitioning and write changes to disk
  17. Partition disks, Write changes to disks? = Yes
  18. Configuring popularity-contest = <your choice>
  19. Software selection, Choose software to install = leave as-is, don't check Graphical desktop environment.
  20. Continue without boot loader = continue
  21. Finish the installation = continue
  22. QEMU will automatically reboot back into the installer due to the initial ramdisk being that used for the installation process, so close QEMU whilst we prep the correct initial ramdisk
Extract the initial ramdisk from the Raspberry Pi installation
QEMU requires the initial ramdisk for the Raspberry Pi distribution in order to load the kernel file system and the kernel modules prior to booting the Raspberry Pi hard disk image. This step extracts the initial ramdisk from the Raspberry Pi hard disk image to pass into QEMU for booting. 

# Create a temporary mount point
mkdir /tmp/QEMU

# Mount the Raspberry Pi hard disk image on the mount point
sudo mount -o loop,offset=$((512*2048)) -t ext3 ./debian6-19-04-2012/debian6-19-04-2012.img /tmp/QEMU

# In the Qemu-arm working directory, create a directory for the Raspberry Pi initrd
mkdir ./boot

# Extract the Raspberry Pi ramdisk from the hard drive image to the QEMU working folder
cp /tmp/Qemu/boot/initrd.img-2.6.32-5-versatile ./boot/initrd.img-2.6.32-5-versatile

Boot the Raspberry Pi Debian installation
# Change the initial ramdisk from the default Debian squeeze ramdisk to the RaspberryPi installed ramdisk, check that the initrd has been changed from the installation ramdisk to the boot ramdisk
qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.32-5-versatile -initrd ./boot/initrd.img-2.6.32-5-versatile -hda ./debian6-19-04-2012/debian6-19-04-2012.img -append "root=/dev/sda1" -m 256

# Login

# Install the desktop managed LXDE warning this takes quite a while c. 1hr on my desktop
apt-get install -y lxde xorg xserver-xorg-video-all

Job done


  1. thanks, tested this working on Windows 7 x64 using the following QEMU command line -

    qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -serial stdio -append "root=/dev/sda2 panic=1" -hda debian6-19-04-2012.img -clock dynticks

    NOTE: I think the -clock option was important

  2. I'm stuck here:

    qemu: could not load initrd './installer/initrd.gz'

  3. I had to rename "initrd" to "initrd.gz".

  4. awesome guide ^^
    however i've got a few questions
    i'm using the new debian "wheezy" image provided by the raspberry guys and with the nev initrd and the new kernel from the debian ftp server everything launchs perfectly

    however, i can't launch the command with -cpu

    qemu-system-arm -M versatilepb -cpu arm1176 -kernel vmlinuz-3.2.0-3-versatile -initrd ./ramdisk1/initrd.gz -hda debianwheezy.img -append "root=/dev/sda1" -m 256

    the screen remains blank and nothing happens, after the removal of -cpu arm1176 the qemu launches the vm without problems ...

    any advise here?

    my second problem:
    after configuring and installing everything in the vm, how do i get this stuff on the sd card?
    is this enough?

    dd bs=1M if=/debianwheezy.img of=/dev/sde

    1. QEMU from the Ubuntu repository doesn't not include arm1176 support (at least at the time I wrote this). To use the arm1176 support I believe you need to compile QEMU yourself and include the arm1176 support in the kernel. I've not tried this but am aware of it see here: http://xecdesign.com/compiling-qemu/

      I think your dd command should work, I'm not sure whether the blocksize matters, you may also need to mount the img file and dd the mounted filesystem, although I'd try your command to start off with. I'm still awaiting for my Pi so haven't been able to test this yet.

    2. To get ARM support for QEMU in Ubuntu, install the "qemu-kvm-extras" package. It is marked transitional, but installs a bunch of packages that eventually provide support for ARM. At least it works for me.

  5. Has anyone managed to get this working for ArchLinuxArm?