This guide is for building your own Arch Linux ARM VM image and runnig in QEMU, UTM, Parallels...
1. qemu-img
2. fdisk
3. kpartx
4. bsdtar
5. wget
6. if you are using QEMU, you may need EFI BIOS code from https://github.com/qemu/qemu/raw/master/pc-bios/edk2-aarch64-code.fd.bz2
7. you also need the alarm (Arch Linux ARM build files) from http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz
qemu-img create archlinux.img 32GBFormat the image into two partition: 1. 200M(+) vfat for EFI (use t in fdisk to add label for EFI); 2. rest space ext4 for root file system
fdisk archlinux.img Become root
sudo -sRead partition info and map to devices
kpartx -av archlinux.img
ls /dev/mapperformat partition refer to ls output
mkfs.vfat /dev/mapper/loop0p1
mkfs.ext4 /dev/mapper/loop0p2mount partition and extract files from tarball
mkdir root
mount /dev/mapper/loop0p2 root
mkdir root/boot
mount /dev/mapper/loop0p1 root/boot
bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C rootedit fstab for kernel reading and startup.nsh for EFI shell
# show UUID for both partitions
# the vfat partition looks like: UUID="XXXX-XXXX"
# and the ext4 one looks like UUID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
blkid
# 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/etc/fstab
# The startup.nsh is read by the EFI as a last resort. We need this to be able to do the initial boot.
nano root/boot/startup.nsh
# 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.imgunmount and exit
umount root/boot
umount root
kpartx -d archlinux.img
sync
exit- create a Linux vm using virtualization
use qemu not hypervisor framework of apple (Arch Linux ARM not support M1, thus need qemu to emulate (Cortex-a72 works fine))- use OpenGL if you need DE
- edit setting -> disk -> delete all the disks -> add a new one (virtio) -> import ->select your image you created in Linux (why? Because UTM creates the images as CDROM not DISK by default, this cause the image NOT writable) (using this method, UTM will create a new disk image from origianl one, and this one is writable, and you can resize it on your need)
- change the cpu from default to Cortex-A72 (an ARM64 CPU, same as raspberry pi 4b(?) which is supported by alarm)
- install
qemufrombrewor build your own, then, you may needsudofor creatingnetdev - prepare image for UEFI BIOS and an additional image for saving BIOS settings:
(if you installed qemu using homebrew) the
dd if=/dev/zero of=pflash0.img bs=1m count=64 dd if=/dev/zero of=pflash1.img bs=1m count=64 dd if=edk2-aarch64-code.fd of=pflash0.img conv=notrunc dd if=edk2-arm-vars.fd of=pflash1.img conv=notrunc
.fdfiles is located under/opt/homebrew/Cellar/qemu/<version-of-qemu>/share/qemu/ - following script will create a
- 8 core cpu with host CPU features enabled
- RAM for 16GB
- Using
virt(alias of newest virt machine) to emulate - Accelation not using
kvmbuthvf(Apple's new Hypervisor Framework) - Network card: virtio-net-pci (user network (can access internet, but cannot detected by other guests))
- Video card: virtio-gpu-pci (OpenGL currently not supported in brew version of qemu)
- Virtual display: using cocoa backend (default under MacOS)
- Usb bus & controller & tablet & mouse & keyboard
- Disk device: virtio-blk-pci
- aarch64 uefi app from qemu, and use a additional image to save bios settings
- A serial device if you need
qemu-system-aarch64 \
-cpu host \
-smp cpus=8,sockets=1,cores=8,threads=1 \
-machine virt \
-accel hvf \
-m 16384 \
-device virtio-net-pci,mac=<your-own-mac-address>,netdev=net0 \
-netdev user,id=net0 \
-device virtio-gpu-pci \
-display cocoa,showcursor=on \
-device nec-usb-xhci,id=usb-bus \
-device usb-tablet,bus=usb-bus.0 \
-device usb-mouse,bus=usb-bus.0 \
-device usb-kbd,bus=usb-bus.0 \
-device qemu-xhci,id=usb-controller-0 \
-device virtio-blk-pci,drive=<your-drive-ID>,bootindex=0 \
-drive if=none,media=disk,id=<your-drive-ID>,file=<path-to-your-image>,discard=unmap,detect-zeroes=unmap -device virtio-rng-pci \
-device virtio-serial-pci \
-drive if=pflash,format=raw,unit=0,file=<path-to-your-efi-app-image(plash0.img)>,readonly=on \
-drive if=pflash,format=raw,file=<path-to-your-efi-var-image(plash1.img)> if you want to use serial but not display (add -nographic flag after above)
Parallels can run vhdx image from the create panel.
qemu-img convert -O vhdx archlinux.img archlinux.vhdxNow you should get into efi shell and the efi shell will read the startup.nsh and boot into Arch Linux (please do follow https://archlinuxarm.org/platforms/armv8/generic to initialize the pacman keys and read about others info)
(for Parallels: Boot Manager -> UEFI shell)
- UTM has a experiential OpenGL video card (need SPICE tools, and graphic performance quite poor (only ~200fps in
glmark2)) - qemu is more flexible (no GPU accerlation)
- paralell is paid but simple (with Hardware Accerlation, has
80009000+ FPS inglmark2, same as other Linux Distro)
Grub:
- the first boot can be loaded by
startup.nsh, if you want to use bootloader likegrub, installaarch64version grub and select the.efifile under ESP in BIOS to add it to the boot options.
- thalamus/ArchLinuxARM-M1: https://gist.github.com/thalamus/561d028ff5b66310fac1224f3d023c12
- ctsrc/README.md: https://gist.github.com/ctsrc/a1f57933a2cde9abc0f07be12889f97f