This gist contains the scripts and configurations to run a QEMU virtual machine with an ARM64 architecture.
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.115.tar.xz
# Download the linux kernel and extract it
$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.115.tar.xz
$ tar -xvf linux-5.15.115.tar.xz
$ pushd linux-5.15.115
$ export ARCH=arm64
$ export CROSS_COMPILE=aarch64-linux-gnu-
$ make defconfig
$ make -j16
$ popd
# Download the QEMU source code
wget https://download.qemu.org/qemu-8.2.6.tar.xz
# Download the QEMU_EFI image, extract and gunzip it
$ wget https://releases.linaro.org/components/kernel/uefi-linaro/16.02/release/qemu64/QEMU_EFI.img.gz
$ wget https://releases.linaro.org/components/kernel/uefi-linaro/15.12/release/qemu64/QEMU_EFI.fd
$ tar -xvf QEMU_EFI.img.gz
$ gunzip QEMU_EFI.img.gz
# prepare
$ git submodule update --init
$ make -C BaseTools
$ source edksetup.sh
$ export GCC5_AARCH64_PREFIX=aarch64-linux-gnu-
# debug
$ build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtQemuKernel.dsc -b DEBUG
# release
$ build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtQemuKernel.dsc -b RELEASE
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make qemu_arm64_defconfig
make -j16
wget https://buildroot.org/downloads/buildroot-2024.05.tar.xz
# For fiptool
$ sudo apt install arm-trusted-firmware-tools
# Download the ARM Trusted Firmware and compile it with the QEMU_EFI image
$ cd ~/cca/arm-trusted-firmware
$ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu all fip DEBUG=0 BL33=~/cca/QEMU_EFI.fd
# debug
$ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu all DEBUG=1
# release
$ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu all
# build with u-boot
$ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL33=../u-boot/u-boot.bin DEBUG=0 all fip
# info of the fip.bin
$ ./tools/fiptool/fiptool info build/qemu/release/fip.bin
# Create a 64MB flash image and write BL1, BL2, BL31, and EFI(u-boot) to it
dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc
dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc
$ sudo apt install -y qemu qemu-utils cloud-utils guestfs-tools
# Download the image from the cloud images
$ wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-arm64.img
# Resize the image to 20G
$ qemu-img resize jammy-server-cloudimg-arm64.img 20GB
# Change the root password
$ sudo virt-customize -a jammy-server-cloudimg-arm64.img --root-password password:coolpass
[sudo] password for benshan:
[ 0.0] Examining the guest ...
[ 7.8] Setting a random seed
[ 7.9] Setting passwords
[ 9.4] Finishing off
# Change the ubuntu user password
$ sudo virt-customize -a jammy-server-cloudimg-arm64.img --password ubuntu:password:coolpass
[ 0.0] Examining the guest ...
[ 2.7] Setting a random seed
[ 2.7] Setting passwords
[ 3.8] Finishing off
# Remove the cloud-init package
$ sudo virt-customize -a jammy-server-cloudimg-arm64.img --uninstall cloud-init
[ 0.0] Examining the guest ...
[ 18.8] Setting a random seed
[ 18.9] Running: apt-get remove -y cloud-init
# Show the image information
$ qemu-img info jammy-server-cloudimg-arm64.img
image: jammy-server-cloudimg-arm64.img
file format: qcow2
virtual size: 20 GiB (21474836480 bytes)
disk size: 598 MiB
cluster_size: 65536
Format specific information:
compat: 0.10
compression type: zlib
refcount bits: 16
Child node '/file':
filename: jammy-server-cloudimg-arm64.img
protocol type: file
file length: 598 MiB (626720768 bytes)
disk size: 598 MiB
# Install the cloud-image-utils
sudo apt-get install cloud-image-utils
# Create a user-data file
cat >user-data <<EOF
#cloud-config
password: asdfqwer
chpasswd: { expire: False }
ssh_pwauth: True
EOF
# Set the user-data to the image
cloud-localds user-data.img user-data
cloud-localds cloud.img cloud.txt
qemu-system-aarch64 -smp 8 -m 4096 -M virt,secure=on \
-nographic \
-bios arm-trusted-firmware/flash.bin \
-device virtio-blk-device,drive=image \
-drive if=none,id=image,file=jammy-server-cloudimg-arm64.img \
-device virtio-blk-device,drive=cloud \
-drive if=none,id=cloud,file=cloud.img \
-netdev user,id=user0,hostfwd=tcp::2222-:22 \
-device virtio-net-device,netdev=user0 \
-virtfs local,path=/home/ubuntu,mount_tag=host0,security_model=mapped,id=host0 \
-cpu cortex-a57
Boot ARM64 virtual machines on QEMU
Ubuntu 22.04 LTS (Jammy Jellyfish) release [20240801]
QEMU arm64 cloud server emulation
How to Run Ubuntu 16.04 Aarch64 (64-bit ARM) Cloud Images on Your Intel/AMD Linux Computer with QEMU