Guide: How to Arch Linux on the Pocket Reform

Intro
This is mostly an educational exercise to understand how the Pocket Reform works. For those interested in booting Arch on the Pocket reform, specifically with the i.MX 8M Plus module, this will walk you through it.

Of note, I built the kernel on a Debian 13 machine. I built the initrd image on an Arch machine. I’m booting Arch on the Pocket using an SD Card.

None of the following commands specify sudo even when needed, so if you don’t know when that is needed, the system will yell at you. You’ll also know it’s time to be careful.

Most importantly, I am not an expert in any of this, so suggestions welcomed, and proceed at your own peril. If you write to the wrong partition you’re going to have a bad time.

SD Card Format
I’m using a 1G partition for /boot and the rest for my filesystem. Both partitions are ext4 and the partition table is DOS. I labeled the partitions reformsdboot and reformsdroot respectively. Mostly because that’s what MNT did.

Bootloader
I have not touched u-boot. In theory you should not need to. I use /boot/extlinux/extlinux.conf to point at the new kernel, dtb, and initramfs. More on that later.

Kernel
I’m pulling the latest stable kernel and checking out the version that the Debian install for the Pocket uses (as of this writing). Then I patch it.

mkdir ~/mnt-build
cd ~/mnt-build
git clone https://source.mnt.re/reform/reform-debian-packages.git
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
git checkout -b pocket-reform-6.16.9 tags/v6.16.9
mnt-patch.sh

mnt-patch.sh

#!/bin/bash

cd ~/mnt-build/linux || exit 1  # your kernel tree

PATCH_LIST=$(find ~/mnt-build/reform-debian-packages/linux/patches6.16 -name "*.patch" | sort)

SUCCESS=0
FAIL=0

for patch in $PATCH_LIST; do
    echo "Applying patch: $patch"
    if patch -p1 --dry-run < "$patch"; then
        patch -p1 < "$patch"
        echo "Applied: $patch"
        ((SUCCESS++))
    else
        echo "Failed: $patch"
        ((FAIL++))
    fi
done

echo
echo "Patch application complete!"
echo "Succeeded: $SUCCESS"
echo "Failed:    $FAIL"
echo "Total:     $((SUCCESS + FAIL))"

There’s probably a better way to do this. That should probably be the title of this post.

Okay, now I grab the config from my Debian install. I do this because grabbing the config from reform-debian-packages doesn’t work. It probably could work if I knew what I was doing. I then build using that config.

cd ~/mnt-build/linux
cp /path/to/debian/boot/config-6.16.9-mnt-reform-arm64 .config
make ARCH=arm64 olddefconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image modules dtbs
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_install INSTALL_MOD_PATH=./modules -j$(nproc)
## Go get some coffee

Make asked me a few questions about new config options and I just chose the defaults. I probably don’t need to make dtbs but I do because why not.

Congrats. You now have a kernel complete with modules for 6.16.9-dirty patched for the MNT family of laptops.

Initial ramdisk
I don’t know if you actually need this, but I happen to have another machine running Arch, so why not use mkinitcpio. I also don’t want to learn about initramfs at this point in my life.

First we need a config file.

# ~/mnt-build/mkinitcpio.conf

MODULES=()
BINARIES=()
FILES=()

HOOKS=(base udev modconf block filesystems keyboard fsck)

COMPRESSION="xz"

Then we need an arch machine with mkinicpio, and our kernel modules.

cp -r ~/mnt-build/linux/modules/lib/modules/6.16.9-dirty [arch machine]/lib/modules/
mkinitcpio -k 6.16.9-dirty -g ~/mnt-build/initrd.img-6.16.9-dirty -c ~/mnt-build/mkinitcpio.conf

dtb
Just use the dtb from the Debian install.

cp [pocket-debian]/boot/dtbs/6.16.9-mnt-reform-arm64/freescale/imx8mp-mnt-pocket-reform.dtb ~/mnt-build/

Arch Filesystem
You can grab a rootfs (ArchLinuxARM-aarch64-latest.tar.gz) from Generic AArch64 Installation | Arch Linux ARM

Install!
Let’s assume your SD Card is mounted to /mnt/sdcard. Don’t forget to mount the boot partition to /mnt/sdcard/boot.

We need to install a few things:

  1. The rootfs we got from Arch Linux Arm
  2. The kernel modules
  3. /etc/fstab
  4. kernel + initramfs + dtb (/boot)
  5. extlinux.conf (also /boot)

Technically that’s all you need to boot, as far as I know. Also note I’m using “-testing” as a postfix because it allows me to keep things straight in my head.

We can start by creating the files we need.

## /boot/extlinux/extlinux.conf

default l0
menu title U-Boot menu
prompt 1
timeout 1


label l0
        menu label Arch Linux arm 6.16.9-dirty TESTING
        linux /Image-testing
        initrd /initramfs-linux-testing
        fdt /imx8mp-mnt-pocket-reform.dtb

        append   ro root=/dev/mmcblk0p2 no_console_suspend cryptomgr.notests ${bootargs} console=tty1

Note that I’ve added root=/dev/mmcblk0p2 so be sure that’s where your filesystem lives on your Pocket Reform. I don’t think this is strictly necessary but I wanted to be sure I knew where I was booting to when I was watching the u-boot console. Also, that extlinux.conf file would be generated from a script on a Debian Sid install from MNT.

Next we need an fstab file.

## /etc/fstab
LABEL=reformsdroot / auto errors=remount-ro 0 1
LABEL=reformsdboot /boot auto errors=remount-ro 0 1

I used labels because that’s what the default system image from MNT does, but any flavor of fstab works. You do you.

Time to untar and copy things over to our SD card.

tar -xzf /path/to/ArchLinuxARM-aarch64-latest.tar.gz -C /mnt/sdcard/
cp -r ~/mnt-buid/linux/modules/lib/modules/6.16.9-dirty /mnt/sdcard/lib/modules/
cp ~/mnt-build/fstab /mnt/sdcard/etc/fstab
cp ~/mnt-build/linux/arch/arm64/boot/Image /mnt/sdcard/boot/Image-testing
cp ~/mnt-build/imx8mp-mnt-pocket-reform.dtb /mnt/sdcard/boot/imx8mp-mnt-pocket-reform.dtb
cp ~/mnt-build/initrd.img-6.16.9-dirty /mnt/sdcard/boot/initramfs-linux-testing
mkdir -p /mnt/sdcard/boot/extlinux
cp ~/mnt-build/extlinux.conf /mnt/sdcard/boot/extlinux/extlinux.conf
sync && sync

Run sync twice for luck. You’ll need it.

Okay, now we’re ready to boot our new Arch install.

“But what about the firmware?” I hear you ask. Well have no fear, firmware is all open source now because it’s 2025 and companies have learned that by opening up their… seriously we’ll get to that later let’s just boot this thing and use wired ethernet for now.

This is the part where you could chroot into the filesystem and do some useful updates. If the thing doesn’t boot, then who cares about updates? Let’s just try to boot it.

First Boot
Assuming any of that worked you should now be sitting pretty at a login for Arch Linux called “alarm”. Do not be alarmed. It just stands for Arch Linux Arm. Puns.

You can log in through ssh with alarm and su to root. Passwords here are the same as the username.

Once you’re root, run some helpful commands.

pacman-key --init
pacman-key --populate archlinuxarm

You can now update your system but be aware that it will copy over your /boot/Image file. If you didn’t use a naming convention like I did you might want to back some stuff up before updating.

How to Wifi
Remember when I joked about how firmware is all open source now? Well you need to install some binaries so your wifi will work, assuming you’re on the i.MX 8M Plus like I am. Don’t worry though, the kind folks over at MNT have you covered.

Let’s start by compiling the kernel module (out of tree) since we happen to have a build machine with the kernel we just finished building.

cd ~/mnt-build
git clone https://source.mnt.re/reform/qcacld2.git
cd qcacld2
./build.sh

Now you should have wlan.ko which you can move to your arch linux filesystem. You should probably also tell the system about this new module you installed. There are also some config files and .bin files that this module will need. It’s all in the qcacld2 repo. Let’s assume you’re moving this stuff over via scp to your new install, we’ll call it pocketarch.

cd ~/mnt-build/qcacld2
scp wlan.ko user@pocketarch:/tmp/
cd debian-meta/usr
tar -czf /tmp/firmware.tgz -C . lib/firmware
scp /tmp/wlan.ko user@pocketarch:/tmp/
scp /tmp/firmware.tgz user@pocketarch:/tmp/

Okay, now over on your pocketarch machine.

## THIS CODE GETS RUN ON YOUR MNT POCKET REFORM
## Running this on your build machine is not good

tar -xzf /tmp/firmware.tgz -C /
cp /tmp/wlan.ko /lib/modules/6.16.9-dirty/extra/
depmod 6.16.9-dirty
modprobe -r ath10k_sdio ath10k_pci ath10k_core
modprobe wlan

And just like that your Wifi should now be “working”. There are still some errors in dmesg, but as far as I can tell my wifi works fine. YMMV.

Nice to Haves
A few things you might want right away are the battery monitor and sound working. Both solutions can be found inside reform-tools. Loading the lpc kernel module will have the added benefit of fixing the odd screen flicker you might be seeing on your display.

cd ~/mnt-build
git clone https://source.mnt.re/reform/reform-tools.git
cd reform-tools/lpc
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C ../../linux/ M=$(pwd) -j$(nproc)

You should have a file now called reform2_lpc.ko. Play the same game you played with the last module to get it loaded.

Sound isn’t working, but just because some of the settings are muted.

alsamixer -c tlv320aic3100

See? Muted. You can check out the script reform-hw-setup inside the bin directory of reform-tools for a handy way to fix this.

  amixer -c 0 sset 'Speaker Driver' on
  amixer -c 0 sset 'Output Left From Left DAC' on
  amixer -c 0 sset 'Output Right From Right DAC' on
  amixer -c 0 sset 'Speaker Analog' 127
  amixer -c 0 sset 'DAC' 127
  amixer -c 0 sset 'HP Analog' 127
  amixer -c 0 sset 'HP Driver' on
  amixer -c 0 sset 'HP Left' on
  amixer -c 0 sset 'HP Right' on

Congrats!

You’re now running Arch Linux on your MNT Pocket Reform.

Hopefully even if you only have a cursory understanding of Linux, this has helped you get a little more knowledge tucked safely away in your brain. Please do not use said knowledge for evil.

6 Likes

I think your post can be a great help for those who want to gain a deeper understanding about how things work together. Thank you for writing it!

The reasons we use partition labels is so that we can use them in /etc/fstab. We are not using the UUID to have a stable /etc/fstab for multiple system images and we are not using entries in /dev because sd-card and emmc are name differently depending on your SoM.

With how the patches are organized, the way you chose to do it is similar to how it’s done in ./linux/build.sh in the reform-debian-packages repo. The problem is that patch files are used in the first place. I’d like to switch this to a more git centric approach where we really can rebase patches but I have yet to find a way that works well… ideas welcome.

It does not because the config from reform-debian-packages is getting applied on top of the Debian config.

Making the dtbs would make sense if you also copied over the dtb you need from reform-debian-packages and then patch the kernel Makefile to build that dtb. But as you already know, re-using the existing blob also works.

You don’t need to. Debian is switching to dracut with this release.

Somebody should be packaging reform-tools for arch linux (hint hint) :wink:

1 Like

Thanks for your comments, much appreciated.

Indeed! I’ve already started down this path but figured I’d post this first then learn what AUR is and how their PKGBUILD works. Just starting to play around here: GitHub - cetola/reform-tools-aur

1 Like