|* 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)|
|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:|
|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.|
|- 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|
|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 \|
|- 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|
|- 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.|
It does work with Parallels, I know that for a fact because I did it on Parallels then did it on qemu after. You've done something wrong or missed something. I also know others have had success with this.
The clue in that screenshot is that if there was actually a filesystem at partition 1 with partition type ESP formatted as vfat it would show up as FS0 in the edk2 shell.
As edk2 isn't detecting a filesystem there's something wrong there - I suspect it's either it's not marked as the ESP partition type (section 2, fourth point), or it's not formatted as vfat (section 3, fourth point).
And I also wrote the
There's a fairly obvious step missing in my instructions for Parallels, which is to create a new VM for ArchLinux.
I just converted a qemu qcow2 image to Parallels, created a new Parallels VM, changed the bios to EFI 64 bit and replaced the hdd file (leaving everything else as default), and it works as expected, booting straight away once it is told to boot from the EFI Shell.
Yes, I moved the converted hdd file (actually, it's a folder), into brand new VM.
btw, I'm using PD version 16.3.1 (50393), which version of PD you're using?
After I booted with Ubuntu live CD, I found that EFI partition is broken (cannot recognized the partition filesystem), but the partition is normal in my
Anyway, after re-built the partition with live CD, everything works well. Thanks!
That's interesting. Definitely sounds as if your image corrupted itself somehow.
I have a theory - it's possible that the data was cached and hadn't been fully written to the image. Unmounting the filesystems will flush the data to the block device, but I wonder if there was still caching of the image file happening.
Because in effect you're mounting a filesystem on a virtual block device from a file on a filesystem on a block device.
There's various places where inconsistency could happen, so I've added a couple of extra steps (delete the device mapper mappings after the unmount, then call sync) to try and ensure data consistency of the image as far as possible - although personally I didn't do either of them any of the times that I did this and didn't have any corruption. But it's certainly possible that it could have been the cause.
Working for me as well, thanks for the writeup, @thalamus
And before that:
It's the kernel upgrade to 5.11.2 that has broken it, it worked fine with 5.11.1. You'll still be able to SSH in though,
It's also broken parallels tools which was working with 5.11.1. I would say it's definitely an upstream bug as there are no relevant changes to the pkgbuild: archlinuxarm/PKGBUILDs@974ab30#diff-bfcabe526f3c51e0ac5db02557d97f8a01d2a685ed02a8b5c6b241ffbce0ae28
So much for linux "stable" updates lol - Greg KH pushes them out at such a ridiculous pace these days that they can't be being well tested, as the regular regressions prove.
I actually found the problem with this - it's the virtio-gpu changes in 5.11 which are throwing a BUG(). I was actually mistaken when I said 5.11.1 worked ok - my Parallels Arch instance was still on 5.10.
Personally I'm not going to be bisecting finding out which commit has broken - Parallels can do that themselves, but the error being thrown was added in this commit which is part of a series to add 'blob resources' to the virtio gpu API but that doesn't necessarily mean there's anything wrong with that commit and I suspect this issue will impact all 5.11 kernels.
Stacktrace here for anyone interested.
I get a weird error trying to convert the image:
I created the image a few times, same result. Any hints here?
I also tried loading the
I've scripted the generation of the
However, it seems Parallels no longer supports UEFI, so something needs to be changed there.
I tried using
Trying to run
This is the script I'm using to execute the above steps: https://git.sr.ht/~whynothugo/m1-vm/tree/f65f02c69114c8ff49de77bad94d9a5224112643/item/prepare.sh
Any ideas? What are you guys doing differently?
No idea, sorry. I uninstalled Parallels when the tech preview stagnated and they released an expensive half baked product (as per their standard business model).
I'd just use QEMU, it works better. If you build the UTM version from source: https://github.com/utmapp/qemu - you don't have to mess about patching it.