Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to boot Arch Linux ARM in QEMU (patched for M1)
/*
* 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.
@david50407

This comment has been minimized.

Copy link

@david50407 david50407 commented Feb 7, 2021

Not worked with parallels...

My EFI shell reports block devices without any filesystem, screenshot below:
image

@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Feb 8, 2021

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).

@david50407

This comment has been minimized.

Copy link

@david50407 david50407 commented Feb 9, 2021

I've tried mkfs.vfat and mkfs.vfat -F32 to format the ESP partition, and information returned from fdisk like this:

unknown-1

And from blkid:

/dev/mapper/loop5p1: UUID="0538-C4DB" TYPE="vfat" PARTUUID="89b1aeb5-6554-d641-a1fa-c3ec5fe24a76"
/dev/mapper/loop5p2: UUID="65924f2e-a2cb-4a5e-9171-68d523533081" TYPE="ext4" PARTUUID="d7339e7f-b663-ce44-b63e-25ac7f6d1e23"

And I also wrote the startup.nsh as provided in this gist.

@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Feb 9, 2021

There's a fairly obvious step missing in my instructions for Parallels, which is to create a new VM for ArchLinux.
There's another step which is also needed, in that you move the converted hdd file into the Parallels VM and replace the default one which is created. But to be honest, I'm presuming you did that as it's blindingly obvious.

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.

Screenshot 2021-02-09 at 15 25 32

@david50407

This comment has been minimized.

Copy link

@david50407 david50407 commented Feb 9, 2021

Yes, I moved the converted hdd file (actually, it's a folder), into brand new VM.
And when I typed fs0: in efi shell, it returns that fs0 is not a valid mapping.
It seems that EDK2 cannot recognized my first partition (BLK1)

image

btw, I'm using PD version 16.3.1 (50393), which version of PD you're using?

@KevSex

This comment has been minimized.

Copy link

@KevSex KevSex commented Feb 9, 2021

All working on my MacBook Air M1 in Parallels 16.3.1 (50393) :)

Only step missing was to install efibootmgr first in step 8 as it wasn't installed by default

sudo pacman -S efibootmgr
@david50407

This comment has been minimized.

Copy link

@david50407 david50407 commented Feb 10, 2021

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 archlinux.img, maybe there's a bug in qemu-img convert or prl_convert that might break datas...
(And also, ls ext4 partition's /boot also throws an error that cannot read datas which should be an empty folder)

Anyway, after re-built the partition with live CD, everything works well. Thanks!

@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Feb 10, 2021

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.

@klofrau

This comment has been minimized.

Copy link

@klofrau klofrau commented Feb 10, 2021

Working for me as well, thanks for the writeup, @thalamus

All working on my MacBook Air M1 in Parallels 16.3.1 (50393) :)

Only step missing was to install efibootmgr first in step 8 as it wasn't installed by default

sudo pacman -S efibootmgr

And before that:

pacman-key --init
pacman-key --populate archlinuxarm
@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Feb 11, 2021

Yep, I'm tempted to say that's out of scope of these instructions, but it kinda isn't because efibootmgr is critical to get it to automatically boot and avoid having to mess about with the edk2 shell.
I'll add it.

@LrwAM

This comment has been minimized.

Copy link

@LrwAM LrwAM commented Feb 22, 2021

Do you hava this problem In the new version(16.3.2 (50531) Technical Preview)?
EFI STUB: Exiting boot services and installing virtual address map
Picture:
截屏2021-02-22 13 48 33
And No more logs are printed

@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Mar 2, 2021

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.

@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Mar 8, 2021

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.

@JPenuchot

This comment has been minimized.

Copy link

@JPenuchot JPenuchot commented May 4, 2021

Used your instructions to get Arch running on my ISP's FTTH internet box, thank you very much!

@WhyNotHugo

This comment has been minimized.

Copy link

@WhyNotHugo WhyNotHugo commented May 18, 2021

I get a weird error trying to convert the image:

Conversion progress: 0%
An internal error(135364618) has occurred.

I created the image a few times, same result. Any hints here?

I also tried loading the vmdk into Parallels (by double clicking on it), but it gives a quite different error:

Parallels Desktop doesn't support the EFI boot loader for this guest OS type or architecture.
@WhyNotHugo

This comment has been minimized.

Copy link

@WhyNotHugo WhyNotHugo commented May 18, 2021

I've scripted the generation of the img based on the steps above:

https://git.sr.ht/~whynothugo/m1-vm/tree/main/item/prepare.sh

However, it seems Parallels no longer supports UEFI, so something needs to be changed there.

@jerrita

This comment has been minimized.

Copy link

@jerrita jerrita commented Jul 5, 2021

In 16.5 parallels, the option -allow-no-os for prl_convert does not seem to work:
image
Is there another solution?

@hunterliao29

This comment has been minimized.

Copy link

@hunterliao29 hunterliao29 commented Jul 5, 2021

Change: qemu-img convert -O vmdk archlinux.img archlinux.vmdk
to : qemu-img convert -O vhdx archlinux.img archlinux.vhdx
which can avoid the use of prl_convert
Then open the archlinux.vhdx in Mac

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 14, 2021

I can’t convert it with prl_convert, I have the same issue, if I put the vhdx file then I can’t boot the vm. Please help
415CEA22-6B94-4E7A-BB0E-7917D096C8E8

@jerrita

This comment has been minimized.

Copy link

@jerrita jerrita commented Jul 14, 2021

I can’t convert it with prl_convert, I have the same issue, if I put the vhdx file then I can’t boot the vm. Please help
415CEA22-6B94-4E7A-BB0E-7917D096C8E8

Refer to the reply above you. Just use: qemu-img convert -O vhdx archlinux.img archlinux.vhdx

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 14, 2021

it's blocked here. I haven't used ssh because the sshd is always dead, I've tried with another vm, but I still have a problem. And I have a question, in step 8, I have to write /dev/sda or sda2? and the uudid that I have to put Is sda2 uudid? Please help
Schermata 2021-07-14 alle 20 32 29
problem
Schermata 2021-07-14 alle 20 01 04

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 15, 2021

when i try to do shh root@ip i have always connection refused

@devilsgrin

This comment has been minimized.

Copy link

@devilsgrin devilsgrin commented Jul 15, 2021

Hello there. I get this error after run " prl_convert archlinux.vmdk" command:
"The source virtual disk contains no operating system."
I sure correctly complated steps. What can i do ?

@devilsgrin

This comment has been minimized.

Copy link

@devilsgrin devilsgrin commented Jul 15, 2021

I try to "qemu-img convert -O vhdx archlinux.img archlinux.vhdx" but unfortunately same error

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 15, 2021

which driver i have to choose to boot arch?

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 15, 2021

after step 9 I have to install arch manually right? because I don't know which driver I have to choose

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 15, 2021

I try to "qemu-img convert -O vhdx archlinux.img archlinux.vhdx" but unfortunately same error

with this, you don't need to convert it, just open the file and boot it

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 16, 2021

Hi, I see journalctl I see that I have some dependency failed, how can I resolve?
9DB0F327-EFBE-4FA5-AC99-DA9AD2144A62

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 16, 2021

the only steps that i'm missing is the driver, please can someone tell me which driver I have to choose?
Please

@WhyNotHugo

This comment has been minimized.

Copy link

@WhyNotHugo WhyNotHugo commented Jul 17, 2021

I tried using qemu-img convert -O vhdx arch-m1.img arch-m1.vhdx. I still get this error:

Parallels Desktop doesn't support the EFI boot loader for this guest OS type or architecture.

Trying to run prl_convert /path/to/archlinux.vhdx --allow-no-os on the image yields An internal error (135364618) has occurred..

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?

@Alessandrorzz

This comment has been minimized.

Copy link

@Alessandrorzz Alessandrorzz commented Jul 27, 2021

HI, I finally booted arch Linux but how can I install parallels tools? the installation doesn't work

@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Aug 10, 2021

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.

@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Aug 10, 2021

Updated the gist to remove all the references to Parallels.

@WhyNotHugo

This comment has been minimized.

Copy link

@WhyNotHugo WhyNotHugo commented Aug 10, 2021

@thalamus

This comment has been minimized.

Copy link
Owner Author

@thalamus thalamus commented Aug 11, 2021

This was intended as a proof of concept and a bit of fun, not as a 'daily driver' for anything.

It certainly wasn't intended for anything other than console work, so video acceleration is entirely irrelevant as far as I'm concerned.

@m-bers

This comment has been minimized.

Copy link

@m-bers m-bers commented Oct 23, 2021

@WhyNotHugo I haven't tried this yet but it seems you can get OpenGL working via this process.

@thalamus I made a script based on your gist and am now working on nightly image builds so thanks very much for this!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment