Overview
Emulate an ARM processor on Intel using CentOS 7 and Qemu.
Conventions
Commands run as root will appear on a black background:
cd ~
Commands run as your regular user will appear on a grey background:
cd ~
Prerequisite Packages
Qemu
dnf -y install qemu-kvm
Cross-compilation
dnf -y 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):
Parameter | Description |
---|---|
export QEMU_AUDIO_DRV=none | Disable audio |
qemu-system-arm | QEMU binary that emulates ARM processors |
-kernel linux/vmlinux | Path to the kernel (built above) |
-cpu arm1176 | Specific ARM processor to emulate |
-m 256M | Memory in MB |
-machine versatilepb | Machine type to emulate. Additional types can be enumerated with qemu-system-arm -machine help |
-no-reboot | |
-serial stdio | Directs 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=disk | Disk image containing the filesystem(s) |