I use a Raspberry Pi as a controller for our X-Carve CNC machine, and it recently stopped booting (my guess is due to SD card corruption from being improperly shut down). I wanted to test out some configuration changes to allow for the SD card to be mounted completely read only, but I didn’t want to have to keep on rebooting the Pi. So I decided to look into emulation (running the Pi in a VM).

The Pi uses an ARM processor, which means that traditional virtual machine approaches like VirtualBox or VMWare wouldn’t be suited. I found a few gists online of people who have done similar things on their Macs that I thought could be useful as a starting point.

I used this as my basis: https://gist.github.com/thomasweng15/af0929114efce3524d55d10f170ff30d

First, one-time setup procedure (I put this in a file setup_qemu.sh)

#!/usr/bin/env bash

# # install qemu
# brew install qemu

# # download the latest stretch kernel and the necessary dtb file
# $ curl -OL https://github.com/dhruvvyas90/qemu-rpi-kernel/raw/master/kernel-qemu-4.14.79-stretch
# $ curl -OL https://github.com/dhruvvyas90/qemu-rpi-kernel/raw/master/versatile-pb.dtb

# # download and unzip the latest raspbian lite
# $ curl -o raspbian_lite_latest.zip -L https://downloads.raspberrypi.org/raspbian_lite_latest
# $ unzip raspbian_lite_latest.zip

export QEMU=$(which qemu-system-arm)
export RPI_KERNEL=kernel-qemu-4.14.79-stretch
export RPI_FS=2019-04-08-raspbian-stretch-lite.img
export RPI_FS_ZIP=2019-04-08_raspbian_lite_stretch.zip
export PTB_FILE=versatile-pb.dtb

# First time setup
# wipe old img file (uncomment this if you are share that's what you want to do!)
if [ -f $RPI_FS ]; then
    rm $RPI_FS
fi
if [ ! -f $RPI_FS ]; then
    unzip $RPI_FS_ZIP
fi

$QEMU -kernel ${RPI_KERNEL} \
    -cpu arm1176 \
    -m 256 \
    -M versatilepb \
    -dtb ${PTB_FILE} \
    -no-reboot \
    -serial mon:stdio \
    -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw init=/bin/bash" \
    -drive "file=${RPI_FS},index=0,media=disk,format=raw"

# Paste the line below (after the comment). press enter, then ctrl-d when it is done booting
# sed -i -e 's/^/#/' /etc/ld.so.preload; sed -i -e 's/^/#/' /etc/ld.so.conf; sed -i -e 's/^/#/' /etc/fstab

Next, the script to run QEMU (I put this in run_qemu.sh):

#!/usr/bin/env bash

export QEMU=$(which qemu-system-arm)
export RPI_KERNEL=kernel-qemu-4.14.79-stretch
export RPI_FS=2019-04-08-raspbian-stretch-lite.img
export PTB_FILE=versatile-pb.dtb

$QEMU -kernel ${RPI_KERNEL} \
    -cpu arm1176 \
    -m 256 \
    -M versatilepb \
    -dtb ${PTB_FILE} \
    -serial mon:stdio \
    -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" \
    -drive "file=${RPI_FS},index=0,media=disk,format=raw" \
    -net user,hostfwd=tcp::5022-:22 \
    -net nic