Thanks to the developers of checkra1n and Corellium I was able to port PostmarketOS to the iPhone 7. Since I was only able to transfer small kernel images to the Phone, I only tested a very minimal PostmarketOS installation, but it is booting :)

Image creation and flashing involves several steps. Lets start with preparing a base image containing PostmarketOS:

pacman -S pmbootstrap
pmbootstrap init
# Work path [/home/onny/.local/var/pmbootstrap]
# Vendor: qemu
# Device codename: aarch64
# Kernel: virt
# User interface: none
pmbootstrap install
pmbootstrap chroot -r 
# use 'apk info' to show installed packages and 'apk del ...' to remove unneeded packages like qemu and linux-kernel
pmbootstrap shutdown

During pmbootstrap init, you can leave most of the defaults as they are. Just select no user interface to avoid large system images.

As you can see above, I’m using the package manager pacman on ArchLinux to install required dependencies. Most of them should be available on other Linux distributions too. If you’re using ArchLinux you can add a custom repository to get some of the tools used in this tutorial:

[...]
[projectinsanity]
SigLevel = PackageOptional
Server = https://onny.project-insanity.org/archlinux

In the next step, we’re going to compile the initramfs image which will contain PostmarketOS. First create the init-script inside the rootfs directory, which is needed by the kernel:

#!/bin/sh
# devtmpfs does not get automounted for initramfs
/bin/mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
exec /sbin/init "$@"

Now we copy the PostmarketOS rootfs to a temporary directory, apply some permissions and package it into a ramdisk archive:

cp -r .local/var/pmbootstrap/chroot_rootfs_qemu-aarch64 /tmp/initramfs
chown -h -R 0:0 /tmp/initramfs
chown -h -R 1000:1000 /tmp/initramfs/var/run/dbus
chmod 755 /tmp/initramfs/init
mkdir /tmp/initramfs/dev
mknod -m 0622 /tmp/initramfs/dev/console c 5 1
cd /tmp/initramfs
sh -c "find . | cpio  --quiet -o -H newc | gzip -9 > /tmp/ramdisk.cpio.gz"

Some of the commands above require root permissions.

Now we can start building the mainline Linux kernel with the patches made by Corellium to support the iPhone 7. It will also include our custom ramdisk containing PostmarketOS:

pacman -S aarch64-linux-gnu-gcc 
cd /tmp
git clone https://github.com/corellium/linux-sandcastle.git
cd linux-sandcastle
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make hx_h9p_defconfig
cp /tmp/ramdisk.cpio.gz .
make -j4
./dtbpack.sh
lzma -z --stdout arch/arm64/boot/Image > arch/arm64/boot/Image.lzma

In the last step we’re going to flash the compiled Linux kernel to the iPhone using the jailbreak-tool checkra1n. You can now connect your iPhone via USB.

Be careful, the following steps are considered safe to use but this is still experimental and could brick your phone. Use it at your own risk!

pacman -S checkra1n-cli git unzip
cd /tmp
git clone https://github.com/corellium/projectsandcastle
cd projectsandcastle/loader
make
checkra1n # put phone into dfu
checkra1n -cpE
./load-linux ../linux-sandcastle/arch/arm64/boot/Image.lzma ../linux-sandcastle/dtbpack

Using the first checkra1n command will acquire DFU mode on the iPhone. Follow the steps in the program until DFU mode is reached, than kill the program so that no jailbreak is installed on the phone. The second checkra1n command requires DFU mode and will reboot you’re iPhone into PongoOS. From there we can load the Linux kernel together with the device tree file using the tool load-linux.

I hope this will bring further progress to custom Linux operating systems on Apple devices. There are already experiments with dual booting and partitioning. So maybe it could be possible in the future to get persistent storage on the phone for Linux systems!

Happy flashing :)

Update May 2020: This post got featured on various news sites. Tuxphones.com (archive), Yahoo.com Taiwan (archive), Fossbytes.com (archive), Cnbeta.com (archive), Softpedia.com (archive), Hackernews (archive) and several more!