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 ifsystemd
fails. Always include it.systemd
: This hook is crucial because it sets up thesystemd
early userspace. If you pickedsystemd
during installation, this is a must.sd-encrypt
: This is thesystemd
-native hook for LUKS decryption. It must be used whensystemd
is present in your hooks, and it replaces the olderencrypt
hook.lvm2
: Comes aftersd-encrypt
because LVM volumes reside on the decrypted LUKS container.- Order matters!
keyboard
beforesd-vconsole
andsd-encrypt
ensures your keyboard is ready for the passphrase.block
ensures 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/grub
Ensure 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_NAME
is 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-0519aea55b50
must be the exact UUID of your raw encrypted partition (/dev/sda2
), andcryptroot
must 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-root
matches 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 -P
builds the initramfs andgrub-mkconfig
runs, GRUB might not include theinitrd
command in its generatedgrub.cfg
if 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_linux
Look for the
for i in
loop 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 done
My Fix: I had to explicitly ensure
"initramfs-linux.img"
was present and ideally early in that list. It appears the default10_linux
on 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-linux
Found initrd image: /boot/initramfs-linux.img
(This is the big one!)- It should also show the kernel command line it’s generating, confirming your
cryptdevice
androot
parameters 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