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



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.

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

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