RaspiOS on 8 core ARM emulation

CPU Emulation is a technique for running code meant for one type of CPU on a different CPU. Generally the instructions are so different that the entire target CPU has to be simulated in software. Other times the instructions are common to the host and target, which leads to higher speed. The image below shows an emulation of a fictitious 8 core ARM32 CPU with 4GB or ram running RaspberryPI OS. This environment can create docker containers which are too big to compile on available hardware (which in this case is a Pi Zero 32 bit computer).

The pages here started out life when the host workstation was an Intel Xeon running Fedora. Currently the host machine is a Ryzen 3700 machine with 16 VCPUs and 64G ram making it ideal for CPU emulation.

The target operating system has also evolved. The raspberry pi foundation now has its own distribution of Linux. This is available in 32 and 64 bit incarnations. As the Raspberry Pis evolved the need for emulation has decreased since they now have 8GB of RAM and 64 bit cpus. However the smaller members of the family, like the Pi Zero, still only have 512MB (which is huge compared to a couple of decades ago, but tiny by today's standards).

The 32 bit members of the family are still memory constrained leading to this requirement.

The host OS is now Ubunu and the guest is Raspberry Pi OS.

Install the emulation software

The first step is to download and install Virtual Machine Manager using apt:
apt install virt-manager
apt install qemu-system-arm

Download the base image

curl \
  -o ~/Downloads/2021-05-07-raspios-buster-armhf-lite.zip \

Next verify the image.

The checksum is in this file located here. Skipping this step invites the crypto-locker attacks.

Run this command to verify the image:
sha256sum ~/Downloads/2021-05-07-raspios-buster-armhf-lite.zip

which will produce output like:

c5dad159a2775c687e9281b1a0e586f7471690ae28f2f2282c90e7d59f64273c  /home/user1/Downloads/2021-05-07-raspios-buster-armhf-lite.zip

Kernel needed

The kernel used here is essentially the same one used to run Fedora 31 on arm32. To make that happen, it's necessary to copy the kernel modules out of the Fedora31 image and place them in the Raspberry Pi OS image. Using other kernels described on various pages around the web was just never going to do the job that was needed here (which is to build docker containers).

virt-install \
   --name rpi \
   --ram 4096 \
   --arch armv7l \
   --machine virt-2.11 \
   --import \
   --os-variant fedora31 \
   --network bridge,source=virbr0,model=virtio \
   --disk 2021-05-07-raspios-buster-armhf-lite.img \
   --boot kernel=/home/user1/VirtLib_VMs/f31arm32/vmlinuz-5.3.7-301.fc31.armv7hl,initrd=/home/user1/VirtLib_VMs/f31arm32/initramfs-5.3.7-301.fc31.armv7hl.img,kernel_args="console=ttyAMA0 rw root=/dev/vda2 rootwait"

Then a little tweaking in the UI to create a preposterous 8 core 32 bit Raspberry Pi with 4GB (some of which can't be used with a 32 bit machine).