ARM on Qemu

Purpose

To create ARM machines, running inside an Ubuntu VM, which can run on either an Intel or ARM64 hosts.

What You Need

Ubuntu Server

I decided to try a headless Ubuntu server, hoping to get both ARM32 and ARM64 images running on it.

Install Ubuntu 20.04.5 on a VMware virtual machine. Include OpenSSH. Remove the virtual CD drive.

(I tried Ubuntu 22.04.2 also and it worked.)

On the Ubuntu server, execute these commands:

sudo apt update

sudo apt install git qemu-system-arm qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virtinst libvirt-daemon virt-manager unzip -y

wget https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-01-12/2021-01-11-raspios-buster-armhf-lite.zip

unzip 2021-01-11-raspios-buster-armhf-lite.zip


rm 2021-01-11-raspios-buster-armhf-lite.zip

git clone https://github.com/dhruvvyas90/qemu-rpi-kernel

sudo chown root:root 2021-01-11-raspios-buster-armhf-lite.img
sudo mkdir /VMs
sudo mv 2021-01-11-raspios-buster-armhf-lite.img /VMs
sudo mv qemu-rpi-kernel /VMs

sudo virsh --connect=qemu:///system net-start default
sudo virsh --connect=qemu:///system net-autostart default

sudo virt-install \
  --name rpios  \
  --arch armv6l \
  --machine versatilepb \
  --cpu arm1176 \
  --vcpus 1 \
  --memory 256 \
  --import  \
  --disk /VMs/2021-01-11-raspios-buster-armhf-lite.img,format=raw,bus=virtio \
  --network bridge,source=virbr0,model=virtio  \
  --nographics \
  --boot 'dtb=/VMs/qemu-rpi-kernel/versatile-pb-buster.dtb,kernel=/VMs/qemu-rpi-kernel/kernel-qemu-4.19.50-buster,kernel_args=root=/dev/vda2 panic=1' \
  --events on_reboot=destroy \
   --osinfo linux2020
You see a Raspian login prompt.

Log in with a username of pi and a password of raspberry

Enabling SSH on the ARM32 VM

On the Raspberry Pi, execute these commands:
sudo raspi-config

Select "Interface Options"
Select SSH
Select Yes
Wait for a minute or two while keys are generated
Select OK
Select Finish

sudo usermod -a -G ssh pi
sudo poweroff

Controlling Qemu VMs

SHOW VMs
sudo virsh --connect qemu:///system list --all
TURN OFF THE GUEST
sudo virsh --connect qemu:///system reset rpios 
RESTART GUEST
sudo virsh --connect qemu:///system start rpios --console
DELETE THE GUEST
sudo virsh --connect qemu:///system undefine rpios

ARM64 Alpine

On the Ubuntu host:

sudo apt install qemu-uefi 

wget https://dl-cdn.alpinelinux.org/alpine/v3.17/releases/aarch64/alpine-standard-3.17.2-aarch64.iso

cp /usr/share/qemu-efi-aarch64/QEMU_EFI.fd flash0.img
truncate -s 64M flash0.img
truncate -s 64M flash1.img

# create qcow2 image
qemu-img create -f qcow2 alpine.qcow2 10G

qemu-system-aarch64 -M virt -cpu cortex-a57 -m 2048 \
-device virtio-net-pci,netdev=net0,romfile="" \
-netdev type=user,id=net0 \
-device virtio-blk-pci,drive=drv0 \
-object rng-random,filename=/dev/urandom,id=rng0 \
-device virtio-rng-pci,rng=rng0 \
-drive format=qcow2,file=alpine.qcow2,if=none,id=drv0 \
-drive if=pflash,format=raw,file=flash0.img,readonly \
-drive if=pflash,format=raw,file=flash1.img \
-nographic \
-device virtio-scsi \
-device scsi-cd,drive=cd \
-drive if=none,id=cd,file=alpine-standard-3.17.2-aarch64.iso


Installing Alpine

Log in as root with no password setup-alpine Go through the Alpine installation root password = P@ssw0rd also student P@ssw0rd use disk as sys poweroff # BOOT WITHOUT THE INSTALL MEDIA On the Ubuntu host: sudo nano /usr/local/setup_br0 ---- #!/bin/bash /usr/sbin/ip link add br0 type bridge /usr/sbin/ip addr add 192.168.60.1/24 dev br0 /usr/sbin/ip link set br0 up ----- sudo chmod +x /usr/local/setup_br0 sudo crontab -e --- @reboot /usr/local/setup_br0 --- sudo mkdir /etc/qemu echo 'allow br0' | sudo tee -a /etc/qemu/bridge.conf nano start_arm64.sh ------ #!/bin/bash qemu-system-aarch64 -M virt -cpu cortex-a57 -m 2048 \ -device virtio-net-pci,netdev=net0,romfile="" \ -netdev type=user,id=net0 \ -device virtio-blk-pci,drive=drv0 \ -object rng-random,filename=/dev/urandom,id=rng0 \ -device virtio-rng-pci,rng=rng0 \ -drive format=qcow2,file=alpine.qcow2,if=none,id=drv0 \ -drive if=pflash,format=raw,file=flash0.img,readonly \ -drive if=pflash,format=raw,file=flash1.img \ -netdev bridge,id=hn1 \ -device virtio-net,netdev=hn1,mac=e6:c8:ff:aa:bb:cc \ -nographic ---- chmod +x start_arm64.sh sudo ./start_arm64.sh Log in as student P@ssw0rd su - apk add nano nano /etc/apk/repositories Uncomment them all, except for /media/cdrom... apk update apk add sudo sudo -lU student echo '%wheel ALL=(ALL) ALL' > /etc/sudoers.d/wheel adduser student wheel sudo nano /etc/network/interfaces --- auto eth1 iface eth1 inet static address 192.168.60.100/24 gateway 192.168.60.1 --- sudo ifdown eth1 sudo ifup eth1 sudo ip addr add 192.168.60.100/24 dev eth1 sudo ip link set eth1 up ip a NOTE THE ALPINE IP ADDRESS Leave this window open Open another ssh window or Terminal on the Ubuntu host In that window, ssh student@192.168.60.100

To Shut Down Alpine

sudo poweroff

To Start Up Alpine

sudo ./start_arm64.sh

Mac M1

For the Mac M1, use Ubuntu 22.04 Server instead of Ubuntu 20.04.

To create the machine, you need a graphical desktop.

Execute these commands to install Gnome:

sudo apt install ubuntu-gnome-desktop
sudo reboot
Make a directory /VMs, move the .img file and the qemu-rpi-kernel directory there, chown to root:root, and cd to /VMs

Use this "sudo virt-install" command:

sudo virt-install \
  --name rpios  \
  --arch armv6l \
  --machine versatilepb \
  --cpu arm1176 \
  --vcpus 1 \
  --memory 256 \
  --import  \
  --disk 2021-01-11-raspios-buster-armhf-lite.img,format=raw,bus=virtio \
  --network bridge,source=virbr0,model=virtio  \
  --nographics \
  --boot 'dtb=qemu-rpi-kernel/versatile-pb-buster.dtb,kernel=qemu-rpi-kernel/kernel-qemu-4.19.50-buster,kernel_args=root=/dev/vda2 panic=1' \
  --events on_reboot=destroy \
  --os-variant=debian9
Proceed as shown above in the "Installing Alpine" section.

After the installation, you have an installed virtual hard disk which can be moved to a headless server to run.

x86_64 Alpine Guest on Mac M1 Hardware

In VMware Fusion, create a new VM
Install Ubuntu 24 Server for ARM (default version)
from https://ubuntu.com/download/server/arm

Customize settings
Change hard disk to 50 GB

Update the installer
Don't encrypt the hard disk
Include OpenSSH

When the install finishes, reboot when you are prompted to
Manually connect and disconnect the CD, forcing the action
Press Enter
Log in 

ip a
 
Connect via SSH

sudo apt update
sudo apt install ubuntu-gnome-desktop
sudo reboot

Log in to a graphical environment
Finish a few more setup options
OPen a Terminal from the start button in the lower left
ip a
connect via SSH

sudo apt install git qemu-system libvirt-clients libvirt-daemon-system bridge-utils virtinst libvirt-daemon virt-manager unzip -y

sudo apt install open-vm-tools open-vm-tools-desktop

wget https://dl-cdn.alpinelinux.org/v3.21/releases/x86_64/alpine-standard-3.21.2-x86_64.iso

qemu-img create -f qcow2 alpine_x86_64.qcow2 10G


From graphical desktop, log out and log in again
From graphical desktop, in a Terminal window:



qemu-system-x86_64 -m 256 -nic user \
  -boot d -cdrom alpine-standard-3.21.2-x86_64.iso \
  -hda alpine_x86_64.qcow2
  
A QEMU windows appears, showing the installation messages!

See https://samsclass.info/127/proj/ARM32_Qemu.htm

Proceed as shown above in the "Installing Alpine" section.

After the installation, you have an installed virtual hard

disk which can be moved to a headless server to run. The result is a system installed on the alpine_x86_64.qcow2 file To launch it after installation, qemu-system-x86_64 -m 256 -nic user \ -hda alpine_x86_64.qcow2 \ -nographic log in as root P@ssw0rd apk add nano nano /etc/apk/repositories Uncomment the community line Save with Ctrl+X, Y, Enter apk update apk add sudo visudo add this line student ALL=(ALL) ALL exit log in as student sudo whoami sudo poweroff Move the alpine_x86_64.qcow2 file to the headless Ubuntu 22 server Ub22_wARM32_M1.zip sudo apt update sudo apt install qemu-system nano start_x86_64.sh --- #!/bin/bash qemu-system-x86_64 -m 256 -nic user -hda alpine_x86_64.qcow2 -nographic --- chmod +x start_x86_64.sh

Sources

RASPBERRY PI ON QEMU
How to run the Raspberry Pi Os in a virtual machine with Qemu and Kvm
Raspberry Pi SSH Access Denied
Enable SSH (Secure Shell) on the Raspberry Pi
Debian on QEMU-emulated ARM-64 aarch64
Run Alpine on QEMU aarch64 Virtual Machine
How to install Ubuntu Server for Arm in a QEMU aarch64 virtual machine
How to connect two aarch64 QEMU guests with a bridge

Posted 2-24-23
Updated with Intel emulation section 1-9-25