Arch Linux ARM on M1 Parallels: Encrypted Root Done Right (A Battle Log & Guide)
So, you’ve decided to tackle Arch Linux ARM on your shiny Apple Mx Mac via Parallels Desktop. Fantastic! You’ve likely made it through the first bits of the installation, but now you want that sweet, sweet full-disk encryption for your root filesystem. You follow the Arch Wiki diligently, but… it just won’t boot. Kernel panics. “Unable to mount root fs on unknown-block(0,0).” Sound familiar?
I’ve been there. After wrestling with this for longer than I’d like to admit, I’ve consolidated the specific steps and common pitfalls that finally got my encrypted Arch ARM VM happily booting. This isn’t a replacement for the official ArchWiki installation guide, but rather a set of crucial hints and corrections, particularly for the ARM and Parallels context.
Let’s dive in.
My Setup Snapshot:
- Host: Apple MacBook M1
- Virtualization: Parallels Desktop
- Guest OS: Arch Linux ARM using the local install from here.
- Disk Layout:
/dev/sda1: 4GB, FAT32, mounted as/boot(EFI partition)./dev/sda2: Rest of disk (approx. 496GB).- Encrypted with LUKS:
cryptsetup luksFormat /dev/sda2 - Decrypted device:
/dev/mapper/cryptroot - LVM Physical Volume (PV):
/dev/mapper/cryptroot - Volume Group (VG):
volgrp - Logical Volumes (LVs):
volgrp-swap: 4GB, for swap.volgrp-root: Rest of space, formatted asext4, mounted as/.
- Encrypted with LUKS:
The Encryption & LVM Journey (The Standard Part)
The initial steps of setting up LUKS on /dev/sda2, then creating the LVM
physical volume, volume group (volgrp), and logical volumes (volgrp-swap,
volgrp-root) on top of /dev/mapper/cryptroot are generally well-covered in
the ArchWiki. Follow those instructions meticulously. Ensure your filesystems
(FAT32 for /boot, ext4 for volgrp-root) are created correctly. Just to note,
the next time I do this, I will likely use btrfs for the root filesystem.
The Initramfs: The Crucial Messenger (mkinitcpio.conf)
This is where the kernel gets its early boot instructions, including how to
decrypt your disk. Since we’re using a systemd-based init (a common choice for
modern Arch installations), our hooks need to reflect that.
Open /etc/mkinitcpio.conf:
sudo vim /etc/mkinitcpio.conf
Find the HOOKS line and ensure it contains the following, in this exact order:
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)
Key takeaways here:
base: Provides essential utilities and a BusyBox recovery shell ifsystemdfails. Always include it.systemd: This hook is crucial because it sets up thesystemdearly userspace. If you pickedsystemdduring installation, this is a must.sd-encrypt: This is thesystemd-native hook for LUKS decryption. It must be used whensystemdis present in your hooks, and it replaces the olderencrypthook.lvm2: Comes aftersd-encryptbecause LVM volumes reside on the decrypted LUKS container.- Order matters!
keyboardbeforesd-vconsoleandsd-encryptensures your keyboard is ready for the passphrase.blockensures the disk devices are visible before encryption.
After editing, regenerate your initramfs with:
sudo mkinitcpio -P
Always watch for errors here! Ensure it successfully builds
/boot/initramfs-linux.img and acknowledges the sd-encrypt and lvm2 hooks.
GRUB: The Bootloader Whisperer (The Sneaky Bits)
GRUB is responsible for loading the kernel and initramfs, and passing kernel parameters. This is where things get particularly tricky on ARM with encryption.
-
Enable Cryptodisk in GRUB: Open
/etc/default/grub:sudo vim /etc/default/grubEnsure this line is present and uncommented:
GRUB_ENABLE_CRYPTODISK="y"Why: This tells GRUB to load its own necessary modules to understand and prompt for encrypted disks before the kernel even starts. Without this, GRUB won’t know what to do with your encrypted
/dev/sda2. -
Kernel Command Line Parameters (
GRUB_CMDLINE_LINUX_DEFAULT): This line passes critical information to the kernel.GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet rd.luks.name=5cf92567-adf8-46ef-816f-0519aea55b50=cryptroot root=/dev/mapper/volgrp-root"Let’s break down
rd.luks.name:rd.luks.name=UUID=YOUR_LUKS_UUID=YOUR_DECRYPTED_NAMEis the most robust way.- My specific working configuration used
rd.luks.name=5cf92567-adf8-46ef-816f-0519aea55b50=cryptroot. WhileUUID=is generally preferred forrd.luks.name(e.g.,rd.luks.name=UUID=your-uuid-here=cryptroot), the bare UUID also worked for me. The key is that5cf92567-adf8-46ef-816f-0519aea55b50must be the exact UUID of your raw encrypted partition (/dev/sda2), andcryptrootmust be the name you want the decrypted volume to have. root=/dev/mapper/volgrp-root: This tells the kernel where your actual root filesystem is after decryption and LVM activation. Make surevolgrp-rootmatches your LVM Logical Volume name exactly.
-
The Hidden Gem: Ensuring GRUB Loads the Initramfs (
/etc/grub.d/10_linux)This was the stealthy culprit in my case! Even if
mkinitcpio -Pbuilds the initramfs andgrub-mkconfigruns, GRUB might not include theinitrdcommand in its generatedgrub.cfgif it doesn’t find the initramfs file under its expected names.Open
/etc/grub.d/10_linux(be careful, this is a GRUB generation script!):sudo vim /etc/grub.d/10_linuxLook for the
for i inloop that iterates through common initramfs filenames. It should look something like this (or similar on ARM):for i in "initramfs-linux.img" \ "initrd.img-${version}" "initrd-${version}.img" \ "initrd-${alt_version}.img.old" "initrd-${version}.gz" \ "initrd-${alt_version}.gz.old" "initrd-${version}" \ "initramfs-${version}.img" "initramfs-${alt_version}.img.old" \ "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ "initrd-${alt_version}" "initramfs-${alt_version}.img" \ "initramfs-genkernel-${version}" \ "initramfs-genkernel-${alt_version}" \ "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \ "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do if test -e "${dirname}/${i}" ; then initrd_real="${i}" break fi doneMy Fix: I had to explicitly ensure
"initramfs-linux.img"was present and ideally early in that list. It appears the default10_linuxon my ARM setup wasn’t correctly prioritizing or finding the standard Archinitramfs-linux.img. Adding"initramfs-linux.img"explicitly as the very first option in that list (or ensuring it’s there) solved the issue of GRUB not loading the initramfs.After making this change, save the file.
The Final GRUB Generation
Now, with all the pieces in place, regenerate your GRUB configuration:
sudo grub-mkconfig -o /boot/grub/grub.cfg
Crucially, watch the output! You should now see lines confirming:
Found Linux image: /boot/vmlinuz-linuxFound initrd image: /boot/initramfs-linux.img(This is the big one!)- It should also show the kernel command line it’s generating, confirming your
cryptdeviceandrootparameters are correct.
Reboot and Victory!
Exit your chroot environment, unmount all partitions, close the LUKS device, and reboot your VM:
exit
sudo umount /mnt/boot
sudo umount /mnt
sudo cryptsetup close cryptroot
sudo reboot
If all steps were followed, you should now be greeted by a passphrase prompt from GRUB, and upon successful entry, your Arch Linux ARM system should boot seamlessly into your encrypted root!
This process was a true test of patience, highlighting that while Arch Linux is incredibly powerful, solving boot issues on non-standard architectures and encrypted setups requires a deep dive into the specifics of each component. Hopefully, this detailed account saves someone else the late nights!
As always, you can add my RSS feed to your reader of choice and if you made it this far thanks for reading!
Chris