Skip to content

Instantly share code, notes, and snippets.

@brimstone
Forked from superswan/raspi.sh
Last active April 27, 2022 01:17
Show Gist options
  • Save brimstone/c75dde2cb42a1c7df50578648b18afed to your computer and use it in GitHub Desktop.
Save brimstone/c75dde2cb42a1c7df50578648b18afed to your computer and use it in GitHub Desktop.
Script for raspberry pi emulation. Will create a QEMU vm with fresh raspian. https://azeria-labs.com/emulate-raspberry-pi-with-qemu/
#!/bin/bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
GIB_IN_BYTES="1073741824"
target="${1:-pi1}"
image_path="./sdcard/filesystem.img"
kernel_version="5.10.63-bullseye"
kernel_path="./kernel/kernel-qemu-$kernel_version"
xz_path="./filesystem.xz"
filesystem_image="https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2022-04-07/2022-04-04-raspios-bullseye-arm64-lite.img.xz"
rpi_kernel="https://github.com/dhruvvyas90/qemu-rpi-kernel/archive/86571772bb993c28bf8b925c202bc66dc63bcd45.zip"
fat_folder="./fat"
mkdir -p sdcard
mkdir -p kernel
if [ ! -e $image_path ]; then
echo -e "${RED}No filesystem detected at ${image_path}!"
echo -e "${BLUE}Downloading filesystem${NC}"
wget -O filesystem.xz $filesystem_image
echo -e "${GREEN}Filesystem downloaded.${NC}"
fi
if [ -e $xz_path ]; then
echo -e "${BLUE}Extracting fresh filesystem...${NC}"
unxz $xz_path
mv -- filesystem "$image_path"
fi
echo -e "${BLUE}Preparing filesystem image${NC}"
qemu-img info $image_path
image_size_in_bytes=$(qemu-img info --output json $image_path | grep "virtual-size" | awk '{print $2}' | sed 's/,//')
if [[ "$(($image_size_in_bytes % ($GIB_IN_BYTES * 2)))" != "0" ]]; then
new_size_in_gib=$((($image_size_in_bytes / ($GIB_IN_BYTES * 2) + 1) * 2))
echo -e "${BLUE}Rounding image size up to ${new_size_in_gib}GiB so it's a multiple of 2GiB...${NC}"
qemu-img resize $image_path "${new_size_in_gib}G"
fi
if [ ! -e $kernel_path ]; then
echo -e "{$BLUE}Preparing Kernel${NC}"
cd kernel
wget -O qemu-rpi-kernel.zip $rpi_kernel
unzip qemu-rpi-kernel.zip
cp qemu-rpi-kernel-*/kernel-qemu-$kernel_version .
cp qemu-rpi-kernel-*/versatile-pb.dtb .
rm qemu-rpi-kernel.zip
rm -rf qemu-rpi-kernel-*
cd ..
fi
root=/dev/mmcblk0p2
kernel=""
if [ "${target}" = "pi1" ]; then
emulator=qemu-system-arm
kernel="./kernel/kernel-qemu-$kernel_version"
dtb="./kernel/versatile-pb.dtb"
machine=versatilepb
memory=256m
root=/dev/sda2
nic="--net nic --net user,hostfwd=tcp::5022-:22"
kernel_pattern=""
elif [ "${target}" = "pi2" ]; then
emulator=qemu-system-arm
machine=raspi2b
memory=1024m
kernel_pattern=kernel7.img
dtb_pattern=bcm2709-rpi-2-b.dtb
append="dwc_otg.fiq_fsm_enable=0"
nic="-netdev user,id=net0,hostfwd=tcp::5022-:22 -device usb-net,netdev=net0"
elif [ "${target}" = "pi3" ]; then
emulator=qemu-system-aarch64
machine=raspi3b
memory=1024m
kernel_pattern=kernel8.img
dtb_pattern=bcm2710-rpi-3-b-plus.dtb
append="dwc_otg.fiq_fsm_enable=0"
nic="-netdev user,id=net0,hostfwd=tcp::5022-:22 -device usb-net,netdev=net0"
else
echo "Target ${target} not supported"
echo "Supported targets: pi1 pi2 pi3"
exit 2
fi
if [ -z "$kernel" ]; then
echo "Searching for kernel='${kernel_pattern}'"
kernel=$(find "${fat_folder}" -name "${kernel_pattern}")
fi
echo "Searching for dtb='${dtb_pattern}'"
dtb=$(find "${fat_folder}" -name "${dtb_pattern}")
if [ -z "${kernel}" ] && [ -z "${dtb}" ]; then
fat_path="./fat.img"
echo -e "{$NC}Extracting partitions"
/sbin/fdisk -l ${image_path} \
| awk '/^[^ ]*1/{print $2, $4}' \
| while read s c; do
dd if=sdcard/filesystem.img of=fat.img bs=512 skip=$s count=$c
done
echo "Extracting boot filesystem"
mkdir -p "${fat_folder}"
fatcat -x "${fat_folder}" "${fat_path}"
echo "Searching for kernel='${kernel_pattern}'"
kernel=$(find "${fat_folder}" -name "${kernel_pattern}")
echo "Searching for dtb='${dtb_pattern}'"
dtb=$(find "${fat_folder}" -name "${dtb_pattern}")
fi
if [ "${kernel}" = "" ] || [ "${dtb}" = "" ]; then
echo -e "{$RED}Missing kernel='${kernel}' or dtb='${dtb}'"
exit 2
fi
echo -e "${GREEN}Booting QEMU machine \"${machine}\" with kernel=${kernel} dtb=${dtb}${NC}"
exec ${emulator} \
--machine "${machine}" \
--cpu arm1176 \
--m "${memory}" \
--drive "format=raw,file=${image_path}" \
${nic} \
--dtb "${dtb}" \
--kernel "${kernel}" \
--append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=${root} rootwait panic=1 ${append} rootfstype=ext4 fsck.repair=yes" \
--no-reboot \
--display none \
--serial mon:stdio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment