I’ve been experimenting with postmarketOS for a long time now. My long-term aspiration is to set up a phone that I can use as a daily driver. I need to overcome a lot of obstacles to achieve this.
Today, my goal is to encrypt the main partition. So if I lose the phone, it doesn’t have all my messaging, email and credentials totally unencrypted. This is a hard requirement before moving forward with a lot of other things.
Encrypting the main partition is a lot more complex on pmOS compared to a regular computing device. On most other devices (desktop, laptop server or even a Raspberry Pi) I would usually boot into a minimal environment with the tools necessary for partitioning, encrypting installation, etc.
postmarketOS takes a rather distinct approach to installation: instead of running the installation and setup process on the device, an entire disk image must be build on another computer, and then flashed over onto the phone. This approach works really well if you have a dozens or hundreds of devices and makes things a bit simpler for devices that don’t have physical keyboards. Personally: I would have preferred a simple installation via SSH.
Preparing a workspace VM ¶
To create a device image, I need a privileged environment with
I’m going to use a VM for this to avoid messing up my system.
First, create a disk image for the VM:
qemu-img create workspace.img 20G
Then, download the Alpine “virtual” image, and run a VM with both the disk and the Alpine installation image installed (notes on qemu usage):
qemu-system-x86_64 --enable-kvm \ -nic user \ -nographic \ -m 1G \ -smp cores=2 \ -drive file=alpine-virt-3.17.3-x86_64.iso,format=raw \ -drive file=workspace.img,format=raw
You might have to drop
--enable-kvm if you hardware doesn’t support KVM. If
aarch64 just use the
aarch64 image and
don’t need to use
x86_64, this is just what matches my architecture.
In the VM, use
setup-alpine and go through the Alpine installation process.
Nothing special needs to be done here.I didn’t bother setting up
ssh here and
left an empty root password.
Then turn off the VM with
poweroff, and start it again, this time without the
installation media and exposing a directory on the host via
qemu-system-x86_64 --enable-kvm \ -nic user \ -nographic \ -m 1G -smp cores=2 \ -drive file=workspace.img,format=raw \ -virtfs local,path=/home/hugo/workspace/oneplus/output,mount_tag=output,security_model=mapped-xattr
Log in as root, and then edit
/etc/apk/repositories. Uncomment the
repositories and remove everything else. E.g.:
http://dl-cdn.alpinelinux.org/alpine/edge/main http://dl-cdn.alpinelinux.org/alpine/edge/community http://dl-cdn.alpinelinux.org/alpine/edge/testing
apk update && apk upgrade -a and then
reboot (the kernel likely gets
updated, so it’s best to boot into the new one).
Building the device images ¶
pmbootstrap. It also expects either
doas to be installed
sudo is the easier choice, since it comes pre-configured to
root to use it for anything (and I’ll be using user
apk add pmbootstrap sudo
sudo a lot. Simply building an image has 155
invocations of so it would need to be configured with
NOPASSWD, plus a
dedicated user for it, and then need to
sudo -u newuser pmbootstrap each
call. I’m going to skip this pointless indirection entirely:
alias pmbootstrap="pmbootstrap --as-root"
Now initialise it:
The default work path is fine, and so is the
edge channel. However, for
vendor and device pick the ones matching your phone. That’s
enchilada respectively for me. See pmOS#Devices to find yours.
There’s a variety of user interfaces available.
phosh is a simple user
friendly one, but not very flexible, tweakable nor developer-oriented. I’m
sxmo takes some learning to initially
understand (especially if you’re coming from iOS/Android), but it’s the most
hackable one and a very good target if you’re wanting to develop applications
and test them on phones.
Additional packages can be specified at this time. For example:
Now it’s time to build the actual image. Contrary to what I initially expected
pmbootstrap build does not build the image (this command builds a single
pmbootstrap install that builds an image, and
pmbootstrap export creates some handy symlinks to it.
To build an image with full disk encryption, use
pmbootstrap install --fde.
Put together, it all looks something like this:
# pmbootstrap install --fde [... lots of output ommitted ...] # pmbootstrap export [13:34:56] (rootfs_oneplus-enchilada) install device-oneplus-enchilada [13:34:58] (rootfs_oneplus-enchilada) install postmarketos-mkinitfs [13:35:00] (rootfs_oneplus-enchilada) mkinitfs postmarketos-qcom-sdm845 [13:35:03] Export symlinks to: /tmp/postmarketOS-export [13:35:03] * boot.img (Fastboot compatible boot.img file, contains initramfs and kernel) [13:35:03] * initramfs-extra (Extra initramfs files in /boot) [13:35:03] * initramfs (Initramfs) [13:35:03] * vmlinuz (Linux kernel) [13:35:03] * oneplus-enchilada.img (Rootfs with partitions for /boot and /) [13:35:03] NOTE: chroot is still active (use 'pmbootstrap shutdown' as necessary) [13:35:03] DONE! # ls -l /tmp/postmarketOS-export/ total 0 lrwxrwxrwx 1 root root 74 Apr 12 13:30 boot.img -> /root/.local/var/pmbootstrap/chroot_rootfs_oneplus-enchilada/boot/boot.img lrwxrwxrwx 1 root root 75 Apr 12 13:30 initramfs -> /root/.local/var/pmbootstrap/chroot_rootfs_oneplus-enchilada/boot/initramfs lrwxrwxrwx 1 root root 81 Apr 12 13:30 initramfs-extra -> /root/.local/var/pmbootstrap/chroot_rootfs_oneplus-enchilada/boot/initramfs-extra lrwxrwxrwx 1 root root 81 Apr 12 13:30 oneplus-enchilada.img -> /root/.local/var/pmbootstrap/chroot_native/home/pmos/rootfs/oneplus-enchilada.img lrwxrwxrwx 1 root root 73 Apr 12 13:30 vmlinuz -> /root/.local/var/pmbootstrap/chroot_rootfs_oneplus-enchilada/boot/vmlinuz
Now mount the directory that’s exposed from the host. Note that
matches the value provided for
mount_tag when specified when running
mount -t 9p -o trans=virtio output /mnt
An copy the images out:
cp /tmp/postmarketOS-export/boot.img /mnt/ cp /tmp/postmarketOS-export/oneplus-enchilada.img /mnt/
It is now safe to turn off the virtual machine:
Flashing the images onto the device ¶
I’m assuming the device is already unlocked (otherwise check the Devices wiki page linked above). Make sure the USB cable is not plugged into the phone and then press and hold VolUp+Power. After it boots, it will indicate “Fastboot” mode and once it’s in the menu you can release first VolUp, then Power. Now plug the USB cable onto the phone and the other end of it to your other computer.
Flash the images onto the device and then reboot it:
doas fastboot flash boot boot.img doas fastboot flash userdata oneplus-enchilada.img doas fastboot reboot
During the initial boot, the main partition will be extended to occupy all of the disk.
The initial installation is now done.