Last active
November 16, 2024 05:37
-
-
Save thalamus/561d028ff5b66310fac1224f3d023c12 to your computer and use it in GitHub Desktop.
How to boot Arch Linux ARM in QEMU (patched for M1)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This document is provided to the public domain under the | |
* terms of the Creative Commons CC0 public domain license | |
*/ | |
How to boot Arch Linux ARM in QEMU (patched for M1) | |
Prerequisites: | |
QEMU - patched for M1 processors - patches: https://github.com/utmapp/qemu | |
A working linux distribution of some description. | |
I personally used Ubuntu 20.10 ARM64 running in Parallels TP to carry out this originally, | |
but any should work, and it doesn't have to be ARM64. | |
The following software on said linux system: | |
qemu-img | |
fdisk | |
kpartx | |
bsdtar | |
wget | |
Additionally, if you wish to use QEMU you may need to download this on your M1 Mac | |
EFI BIOS - https://github.com/qemu/qemu/raw/master/pc-bios/edk2-aarch64-code.fd.bz2 | |
if you have installed QEMU from source, it will be located in the 'share' folder within | |
the installation prefix. | |
Knowledge of the command line. | |
Commands prefixed with $ are ran as a normal user and those prefixed # require root. | |
$ sudo -s is a suitable way of getting root. | |
1) Create a suitable directory, download the Arch tarball and create the raw image: | |
$ mkdir ~/alarm | |
$ cd ~/alarm | |
$ wget http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz | |
$ qemu-img create archlinux.img 32GB | |
2) Partition the image with fdisk: | |
$ fdisk archlinux.img | |
- then g (to create a new GPT partition table) | |
- then n (to create a new partition), then enter twice, then +200M and enter | |
- then t (to change the type), then 1 for EFI System Partition | |
- then n and enter three times, then w to write changes and exit | |
3) Become root, create the loop devices and format the partitions of the image. | |
$ sudo -s | |
# kpartx -av archlinux.img | |
# ls /dev/mapper - you should see two new devices - something like loop6p1 / loop6p2 | |
# mkfs.vfat /dev/mapper/loop6p1 | |
# mkfs.ext4 /dev/mapper/loop6p2 | |
4) Mount the partitions and extract the Arch Linux ARM tarball to them. | |
# mkdir root | |
# mount /dev/mapper/loop6p2 root | |
# mkdir root/boot | |
# mount /dev/mapper/loop6p1 root/boot | |
# bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C root | |
5) Edit /etc/fstab and create /boot/startup.nsh files. | |
# blkid | |
- you'll need the UUID for both partitions - the vfat partition looks like: UUID="XXXX-XXXX" | |
and the ext4 one looks like UUID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" | |
# nano root/etc/fstab | |
Paste the following (with the correct UUIDs to suit your system of course: | |
/dev/disk/by-uuid/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX / ext4 defaults 0 0 | |
/dev/disk/by-uuid/XXXX-XXXX /boot vfat defaults 0 0 | |
# nano root/boot/startup.nsh | |
The startup.nsh is read by the EFI as a last resort. We need this to be able to do the initial boot. | |
This should look exactly like this (with the correct UUID for the ext4 partition): | |
Image root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw initrd=\initramfs-linux.img | |
6) Unmount the partitions and exit from the root shell. | |
# umount root/boot | |
# umount root | |
# kpartx -d archlinux.img | |
# sync | |
# exit | |
7) Convert the image to a qcow2 (optional, but much smaller), and create flash partitions with EFI BIOS. | |
$ qemu-img convert -O qcow2 archlinux.img archlinux.qcow2 | |
- then move the image to your M1 Mac filesystem | |
In the Mac terminal - do the following: | |
$ truncate -s 64M flash0.img (this is for the EFI BIOS) | |
$ truncate -s 64M flash1.img (this is to store EFI variables) | |
- Unzip the EFI Bios file | |
$ dd if=/path/to/edk2-aarch64-code.fd of=flash0.img conv=notrunc | |
- Put the flash0.img, flash1.img and archlinux.qcow2 into a suitable folder. | |
Use a command similar to this to boot the VM: | |
qemu-system-aarch64 -L ~/bin/qemu/share/qemu \ | |
-smp 8 \ | |
-machine virt,accel=hvf,highmem=off \ | |
-cpu cortex-a72 -m 4096 \ | |
-drive "if=pflash,media=disk,id=drive0,file=flash0.img,cache=writethrough,format=raw" \ | |
-drive "if=pflash,media=disk,id=drive1,file=flash1.img,cache=writethrough,format=raw" \ | |
-drive "if=virtio,media=disk,id=drive2,file=archlinux.qcow2,cache=writethrough,format=qcow2" \ | |
-nic user,model=virtio-net-pci,hostfwd=tcp::50022-:22 -nographic \ | |
-device virtio-rng-device -device virtio-balloon-device -device virtio-keyboard-device \ | |
-device virtio-mouse-device -device virtio-serial-device -device virtio-tablet-device \ | |
-object cryptodev-backend-builtin,id=cryptodev0 \ | |
-device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 | |
- QEMU should boot the VM automatically after dropping to the EFI shell. | |
8) Upon successful first boot, login as root, password root | |
You now need to get pacman up and running, update the system and install efibootmgr: | |
# pacman-key --init | |
# pacman-key --populate archlinuxarm | |
# pacman -Syu | |
# pacman -S efibootmgr | |
We now need to create the EFI boot entry: | |
# blkid - you'll need the UUID for vda2 | |
# efibootmgr --disk /dev/vda --part 1 --create --label "Arch Linux ARM" --loader /Image --unicode 'root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw initrd=\initramfs-linux.img' --verbose | |
- you should get output which shows a list of the boot entries. | |
9) Poweroff and boot the system again | |
# poweroff | |
- start the QEMU VM | |
- this time it should just boot without dropping into an EFI shell. | |
10) Post Install notes | |
Arch Linux ARM is a bit basic out of the box - you will probably want to set a suitable locale, | |
create a user and install some useful stuff, | |
You'll find info on doing all of that on the Arch Wiki - https://wiki.archlinux.org | |
- which, in my opinion, is one of the best distro wikis available. | |
This was originally written up mainly from memory and bash history - but the missing bits have been added! | |
Edited on 10/08/2021 to remove all references to Parallels - use QEMU instead. |
I found the solution, and wrote a self-contained script to automate the process, it takes about 5 minutes to run, and all you have to is download and run the script, and follow a few manual steps. See https://github.com/bantling/tools/tree/master/qemu-vms.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Actually, it's exactly the same steps - I'm just using a Linux VM rather than a physical machine to create the image file, partition it, make the filesystems, and extract the base image to it. It's still Linux creating the file with the same tools. Maybe you used a different Linux distro, but that doesn't matter.
Judging by the dating of this article, it is probably written for QEMU 6.2, and I am using 7.0, which does cause some known issues on Mac OS as I am finding, so that is probably the real difference.
I read at utmapp/UTM#2333 that using the ESC key can allow quickly bypassing the delay and going straight to the EFI shell. This did in fact work for me in two ways:
So it seems I'm probably right about some kind of UEFI boot order issue. I've tried various things I found online, and none of them seem to work, so I'm going with QEMU 7 is doing something different that somehow affects EFI. I have a work around that does not require waiting a couple of minutes, so am satisfied for now :)