Emulating a 32-bit Raspberry Pi ARM 7 on CentOS Linux with Qemu

By | 2020-Mar-06

Overview

Emulate an ARM processor on Intel using CentOS 7 and Qemu.

Prerequisite Packages

Qemu

# dnf install qemu-kvm

Cross-compilation

# dnf install bc bison flex gcc git glibc-2.28-101.el8.i686 libstdc++-devel.i686 make openssl-devel ncurses ncurses-devel zlib.i686

Acquire Resources

Create a working directory in your unprivileged user home directory and clone the raspbian kernel source:

$ mkdir -p ~/git/raspberrypi
$ cd ~/git/raspberrypi
$ git clone --depth=1 https://github.com/raspberrypi/linux

Also get the Raspbian toolchain:

$ git clone https://github.com/raspberrypi/tools

Download a current version of Raspbian from downloads.raspberrypi.org and unpack. This example uses Raspbian Lite 2020-02-14:

$ wget http://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2020-02-14/2020-02-13-raspbian-buster-lite.zip
$ unzip 2020-02-13-raspbian-buster-lite.zip

Inspect the Raspbian Image

$ fdisk -l 2020-02-13-raspbian-buster-lite.img

The output will show two partitions. When we emulate, this img file will be handed off as hda, so these two partitions will be seen by the emulator as sda1 and sda2.

Configure and Cross-Compile Kernel

Executing $ file ${HOME}/git/raspbian/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc reveals that the Linaro ARM cross-compiler in the Raspbian toolchain is dynamically linked; necessitating the i686 glibc, libstdc++, and zlib packages installed (above).

The kernel will be configured to support a minimal number of features, architectures, and filesystems:

$ cd linux
$ export KERNEL="kernel7"
$ export ARCH="arm"
$ export CROSS_COMPILE="${HOME}/git/raspbian/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-"
$ make bcm2709_defconfig
$ make menuconfig
$ make all
$ cd ..

ARM/Raspberry Pi Emulation

$ export QEMU_AUDIO_DRV=none
$ qemu-system-arm \
-kernel linux/vmlinux \
-cpu arm1176 \
-m 256M \
-machine versatilepb \
-no-reboot \
-serial stdio \
-append "root=/dev/sda2 panic=1 rootfstype=ext4 rw init=/bin/bash" \
-drive file=2020-02-13-raspbian-buster-lite.img,format=raw,index=0,media=disk

Command breakdown (please see man qemu-system-arm for further detail):

ParameterDescription
export QEMU_AUDIO_DRV=noneDisable audio
qemu-system-armQEMU binary that emulates ARM processors
-kernel linux/vmlinuxPath to the kernel (built above)
-cpu arm1176Specific ARM processor to emulate
-m 256MMemory in MB
-machine versatilepbMachine type to emulate. Additional types can be enumerated with qemu-system-arm -machine help
-no-reboot
-serial stdioDirects serial output to stdio (linux only)
-append “root=/dev/sda2 panic=1 rootfstype=ext4 rw init=/bin/bash”Options to pass to the kernel to describe filesystem details and initial processes
-drive file=2020-02-13-raspbian-buster-lite.img,format=raw,index=0,media=diskDisk image containing the filesystem(s)