Migrating MNT Reform to ArchLinux
By default MNT Reform2 laptop comes with Debian SID image. At least that's what I got with my DYI kit. The image comes on SD card, and by default the boot switch on SoM is set to boot from SD Card. SID is fairly bleeding edge, however I still feeling myself awkward working on Debian, even though the bleeding edge is one of the reasons I'm in favour of Arch Linux. Since I have NVME which is considerably faster than SDCard, I decided to combine migration to NVME drive with migration to Arch Linux. Also as there is no boot security so far, the migration will be to encrypted LUKS2 partitions (FDE).
It seems logical to switch SoM to eMMC boot and get rid of SDCard whatsoever, however I'm still playing with kernel and DTB and other boot-related matters so having boot on SD Card seems ok to me. At least for now.
That means the system still boots from SD: u-boot, kernel, then reform-init starts (pre-set kernel params in u-boot) to perform customizable OS start. This customizable start checks existence of file /reform-boot and content of that file (text string) determines which OS from which storage is being initialized.
The script is capable to recognize following keywords:
- usb - to boot from first USB mass storage device (actually from /dev/sda1)
- nvme - to boot from first nvm drive (actually from /dev/nvme0n1p1)
- anything else, including absence of the file, just continuing boot from SD
The script is also able to recognize LUKS partition on selected device (usb, nvme or sd) and will try to open the LUKS for the root partition.
That means I need to do following:
- Partition NVME drive
- Create LUKS partition
- Open LUKS and create root FS on it
- Mount root FS and install Arch into it
- Chroot into Arch and finalze the install (configure the system)
- Create /reform-boot-media file with word nvme and reboot
First thing first and I screwed a bit the first step. I've created first partition for swap, second for root and third for home. Before I realized the script always tries first partition. And I realized that at that last step, after system was already installed, so it was too late to fix it. So instead I've fixed reform-init script by making it being able to understand not just device type but also partition number. If you don't want to do that just make sure your root partition is first.
So I ended up with this partitioning: first partition is kind of boot or init or whatever (currently unused), second is swap (to be able to suspend-to-disk), third is root and last is home:
# fdisk -l /dev/nvme0n1 Festplatte /dev/nvme0n1: 931,51 GiB, 1000204886016 Bytes, 1953525168 Sektoren Festplattenmodell: WDC WDS100T2B0C-00PXH0 Einheiten: Sektoren von 1 * 512 = 512 Bytes Sektorgröße (logisch/physikalisch): 512 Bytes / 512 Bytes E/A-Größe (minimal/optimal): 512 Bytes / 512 Bytes Festplattenbezeichnungstyp: gpt Festplattenbezeichner: 798BE574-4AD9-0642-BD83-89CD93576F48 Gerät Anfang Ende Sektoren Größe Typ /dev/nvme0n1p1 2048 2099199 2097152 1G Linux-Dateisystem /dev/nvme0n1p2 2099200 10487807 8388608 4G Linux Swap /dev/nvme0n1p3 10487808 981469183 970981376 463G Linux root (ARM-64) /dev/nvme0n1p4 981469184 1191184383 209715200 100G Linux Home
Note: you can avoid patching reform-init script by simply making root crypto-volume the first and moving boot and swap to the end.
As you see the disk is under-provisioned, there's plenty of free space. The next thing - LUKS. While it is possible to store LUKS key on the disk and have it in crypttab - this would defeat the security, hence I decided to use classic passphrase based initialisation (something I know). And also the home partition would also be LUKS encrypted, and using different passphrase (we'll come to that later).
$ sudo cryptsetup luksFormat /dev/nvme0n1p3 WARNUNG! ======== Hiermit werden die Daten auf »/dev/nvme0n1p3« unwiderruflich überschrieben. Sind Sie sicher? (Tippen Sie 'yes' in Großbuchstaben): YES Geben Sie die Passphrase für »/dev/nvme0n1p3« ein: $ sudo cryptsetup open /dev/nvme0n1p3 cryptroot Geben Sie die Passphrase für »/dev/nvme0n1p3« ein: $ sudo mkfs.ext4 /dev/mapper/cryptroot $ sudo mount /dev/mapper/cryptroot /mnt
That completes first 3 steps and starts fourth step. Now we need to obtain Arch Linux installation image. Since this is ARM laptop we definitely need to use ALARM or ArchLinuxARM images. And from there we need ARMv8 AArch64 Multi-Platform image. Technically we can also take rpi-aarch64 as RPi3 uses A53 cores, same as iMX8MQ. I don't think there's any major difference between the two and I think I actually used rpi-aarch64, don't remember now. Either way it's quite barebone image and you'd need to beef it up before it becomes usable. Don't forget to check signature of the image, for which also download sig file and then do:
$ gpg --verify Downloads/ArchLinuxARM-aarch64-latest.tar.gz.sig gpg: die unterzeichneten Daten sind wohl in 'Downloads/ArchLinuxARM-aarch64-latest.tar.gz' gpg: Signatur vom Sa 20 Nov 2021 04:46:53 CET gpg: mittels RSA-Schlüssel 68B3537F39A313B3E574D06777193F152BDBE6A6 gpg: Signatur kann nicht geprüft werden: Kein öffentlicher Schlüssel $ gpg --keyserver keyserver.ubuntu.com --search-keys \ 68B3537F39A313B3E574D06777193F152BDBE6A6 gpg: data source: http://126.96.36.199:11371 (1) Arch Linux ARM Build System <firstname.lastname@example.org> 4096 bit RSA key 77193F152BDBE6A6, erzeugt: 2014-01-18 Keys 1-1 of 1 for "68B3537F39A313B3E574D06777193F152BDBE6A6". Eingabe von Nummern, \ Nächste (N) oder Abbrechen (Q) > 1 gpg: Schlüssel 77193F152BDBE6A6: Öffentlicher Schlüssel "Arch Linux ARM Build System \ <email@example.com>" importiert gpg: Anzahl insgesamt bearbeiteter Schlüssel: 1 gpg: importiert: 1 $ gpg --verify Downloads/ArchLinuxARM-aarch64-latest.tar.gz.sig gpg: die unterzeichneten Daten sind wohl in 'Downloads/ArchLinuxARM-aarch64-latest.tar.gz' gpg: Signatur vom Sa 20 Nov 2021 04:46:53 CET gpg: mittels RSA-Schlüssel 68B3537F39A313B3E574D06777193F152BDBE6A6 gpg: Korrekte Signatur von "Arch Linux ARM Build System \ <firstname.lastname@example.org>" [unbekannt] gpg: WARNUNG: Dieser Schlüssel trägt keine vertrauenswürdige Signatur! gpg: Es gibt keinen Hinweis, daß die Signatur wirklich dem vorgeblichen \ Besitzer gehört. Haupt-Fingerabdruck = 68B3 537F 39A3 13B3 E574 D067 7719 3F15 2BDB E6A6
Here I tried to check the sig against the file, gpg complained it cannot find the key of the signature, so I went to ubuntu keyserver and imported the key. Then tried again to check the signature - gpg confirmed correct signature however complained that I don't trust the key. Which is ok, I don't need to (as we don't know the person who issued the key). It is sufficient that the signature is valid and the key exists and its fingerprint matches to the one specified on download page.
Now just extract the stage image to the mounted root partition and chroot to it:
$ sudo tar xvf Downloads/ArchLinuxARM-aarch64-latest.tar.gz -C /mnt $ sudo mount -t proc proc /mnt/proc $ sudo mount -t sysfs sysfs /mnt/sys $ sudo mount -o bind /dev /mnt/dev $ sudo chroot /mnt /usr/bin/bash # . /etc/profile
After last command you should become a root inside barebone archlinux installation. Now you can do pacman -Syu to perform initial system and keyring update and then you can follow official Arch Install manual to finalize the setup, starting perhaps from Timezone section and skipping initramfs.
Since we have network and sway config already on SD card we can simply copy it over to simplify migration: from another terminal (which is not in Arch chroot) do
$ sudo cp /etc/systemd/network/wlan.network /mnt/etc/systemd/network/ $ sudo cp /etc/wpa_supplicant/wpa_supplicant-wlp1s0.conf \ /mnt/etc/wpa_supplicant/wpa_supplicant-wlp1s0.conf $ sudo cp /etc/sway/config /mnt/etc/sway/config $ sudo cp /etc/sway/config.d/* /mnt/etc/sway/config.d/ $ sudo cp /etc/systemd/sleep.conf /mnt/etc/systemd/ $ sudo cp /etc/systemd/system/reform-sleep.service /mnt/etc/systemd/system/ $ sudo cp /usr/local/bin/standby /mnt/usr/local/bin/standby $ sudo cp -r /usr/lib/firmware /mnt/usr/lib/ $ sudo cp -r /usr/lib/modules /mnt/usr/lib/
While u-boot, kernel and DTB/FDT will be booting from either SD or eMMC (depending on boot switch on SoM), the modules and firmware will be loaded by systemd/udev from newly mounted root - therefore I also copied those over.
You may need to install corresponding packages before - to create target dirs. wpa_supplicant and systemd will be there but sway needs to be pre-installed. Once done - the only remaining part is user profile migration, and as prereq cryptohome setup.
Until secure-boot (HABv4) is implemented I don't trust the boot process and therefore will be using separate encryption keys (sacrifice accesibility for confidentiality and integrity). So I'll be creating a new LUKS2 volume on next partition (p4) and moving home from SD card to this encrypted volume:
$ sudo cryptsetup luksFormat /dev/nvme0n1p4 WARNUNG! ======== Hiermit werden die Daten auf »/dev/nvme0n1p4« unwiderruflich überschrieben. Sind Sie sicher? (Tippen Sie 'yes' in Großbuchstaben): YES Geben Sie die Passphrase für »/dev/nvme0n1p4« ein: $ sudo cryptsetup open /dev/nvme0n1p4 crypthome Geben Sie die Passphrase für »/dev/nvme0n1p4« ein: $ sudo mkfs.ext4 /dev/mapper/crypthome $ sudo mount /dev/mapper/crypthome /mnt/home
Now at chrooted console create a new user for yourselves, making sure the UID is the same as on SD card (whichg in most cases will be 1000, but you may explicitly request specific UID/GID with -u and -g options:
# groupadd -g 1000 ruff # useradd -m -u 1000 -g ruff -G wheel ruff # passwd ruff # vim /etc/sudoers
The last command assumes you've added sudo with pacman -Syu sudo and then enables sudo for either group wheel or user. And then move all home content to new location:
$ mv ~/.* /mnt/home/ruff/ $ mv ~/* /mnt/home/ruff/ $ cp /mnt/home/ruff/.bashrc ~/ $ cp /mnt/home/ruff/.bash_profile ~/
Now we need to set home automount, for which we need to describe our home cryptovolume (root volume is explicitly opened by reform-init but home needs to be hooked into systemd init sequence) and either add it inot fstab or describe as a mount unit. I'll be making later option here:
# echo -e "home\t/dev/nvme0n1p4\tnone" >> /etc/crypttab # vim /etc/systemd/system/home.mount [Unit] Description=home.mount Requires=dev-mapper-home.device Conflicts=umount.target Before=local-fs.target systemd-user-sessions.service umount.target After=dev-mapper-home.device local-fs-pre.target email@example.com RequiresMountsFor=/ [Mount] Where=/home What=/dev/mapper/home Options=rw,relatime Type=ext4 [Install] WantedBy=user.slice # mkdir /etc/systemd/system/user.slice.wants/ # ln -s /etc/systemd/system/home.mount /etc/systemd/system/user.slice.wants/home.mount # ln -s /usr/lib/systemd/system/wpa_supplicant@.service \ /firstname.lastname@example.org
Note that I've also enabled wifi service here using this opportunity.
That should be it, rebooting now should attempt to open root luks volume, then it will prompt for home luks volume, and then for user login. 3 password prompts, a bit too much, hopefully will reduce it in the future with introduction of secure boot and nitrokey key decryption.
$ sudo umount -R /mnt $ sudo cryptsetup close crypthome $ sudo cryptsetup close cryptroot $ echo nvme | sudo tee /reform-boot-medium $ reboot
Note that in my case I made echo nvme0n1p3 | sudo tee /reform-boot-medium to boot from third partition with patched reform-init.
While I did copy the sleep helper unit I didn't enable it, so here is good time to enable it after booting into system. Also it is helpful to add alsa controls tweaks to enable sound:
$ sudo systemctl enable reform-sleep $ vim .bash_profile test -f ~/.bashrc && . ~/.bashrc || . /etc/profile if [[ $(tty) = "/dev/tty1" && "x$WAYLAND_DISPLAY" = "x" ]] then export QT_QPA_PLATFORM=wayland export SDL_VIDEODRIVER=wayland export MOZ_ENABLE_WAYLAND=1 export GTK_THEME=Adwaita:dark export ETNA_MESA_DEBUG=nir dbus-update-activation-environment --systemd SDL_VIDEODRIVER QT_QPA_PLATFORM dbus-update-activation-environment --systemd GTK_THEME amixer -c0 sset 'Right Output Mixer PCM' on amixer -c0 sset 'Left Output Mixer PCM' on amixer -c0 sset Playback 244 amixer -c0 sset Speaker 122 exec /usr/bin/sway fiLink... Wed Feb 2 22:37:48 2022