The on-device installer provides a graphical interface to configuring the operating system before it gets installed.
- 1 Features
- 2 Overview
- 3 Generating an installer image
- 4 Development
- 5 How it works
- 6 Related
- Install any mobile OS, not just postmarketOS
- Full disk encryption (optional)
- Set the user password (numeric PIN, as expected by Phosh and Plasma Mobile)
- Set up a dedicated ssh user (optional) (related: calamares-extensions#6)
- Choice between installing to eMMC or SD card (postmarketos-ondev#22).
It's far from perfect, but what's there works reliably and should give a good mobile installer base to iterate upon.
The on-device installer is dual-booting between the installer OS and target OS.
Installer OS is the operating system running Calamares with the mobile module (calamares-extensions#3). In theory, any OS could be used as installer OS. However, postmarketOS as installer OS should be the most straight forward way, so it's highly recommended to produce a working image with that first. This article assumes that postmarketOS is the installer OS.
Target OS is the operating system that will be installed. It must be able to:
- unlock encrypted partitions on boot, with osk-sdl or similar (source, pmOS, Debian)
- extend rootfs space on first boot
Generating an installer image
init and select the device you would like to install. The selected UI is only relevant if postmarketOS is the target OS. Everything else can be left at default values.
$ pmbootstrap init
Note that you can automate above step as follows:
$ yes "" | pmbootstrap init $ pmbootstrap config device pine64-pinephone
If the target OS is not postmarketOS, set the boot partition to at least the size of the boot partition of the target OS (in MiB):
$ pmbootstrap config boot_size 300
If you run into "not enough free space" errors later on (#1904), you can add extra free space to the rootfs image too (in MiB).
$ pmbootstrap config extra_space 500
Before the generation of the image is explained, a quick note on the debug user. The installer OS will have a debug user with the username
user and password
y. This user is created in the installer OS, but of course not in the target OS. The installer OS also has SSH enabled by default and listens on all interfaces. You can login as the debug user either via serial, or with SSH over USB Network.
Consider disabling the debug user in production images, if you expect the target device to be available on a network (e.g. Raspberry Pi). To disable the debug user, install a file to
$ touch empty $ pmbootstrap install --ondev --cp empty:/no-debug-user
postmarketOS as target OS
More or less, the following command. See
pmbootstrap install -h for details.
$ pmbootstrap install --ondev [--sdcard=...]
Foreign target OS
Create a working directory like
~/code/ondev-mydistro, where you store the configuration files below. These will be placed in the installer OS with the
pmbootstrap command listed even further below.
# Example for what would probably be needed for Mobian --- # Target OS osName: "mobian" userInterface: "Phosh" version: "2020-11-26" username: "mobian" # Target device arch: "aarch64" device: "PINE64 PinePhone" # Commands running in the installer OS cmdMkfsRoot: "mkfs.ext4 -L 'mobian'" # Commands running in the target OS (chroot) # sshd isn't installed in mobian by default cmdSshdEnable: "true" cmdSshdDisable: "true" # Placeholder to be filled in by ondev-boot.sh targetDeviceRoot: "/dev/unknown"
postmarketos-ondev configures Calamares to run the shellprocess module at the very end of the installation. Prepare a
# Reference: # https://github.com/calamares/calamares/blob/master/src/modules/shellprocess/shellprocess.conf --- dontChroot: true timeout: 1200 script: # Rename pmOS_install partition to pmOS_deleteme - tune2fs -L pmOS_deleteme /dev/disk/by-label/pmOS_install # Replace installer OS boot partition with the boot partition from image # NOTE: Probably need to update the bootloader of the install medium too. # When I tested it with mobian on the PinePhone, u-boot would look for the # wrong dtb, uInitrd, vmlinuz files. So add the file(s) with # 'pmbootstrap install --ondev --cp' (see below) and then put a new dd # command here to flash it to the install medium. - dd if=/mnt/postmarketos-ondev-boot-img of=$ONDEV_BOOT_PARTITION bs=1M - reboot
Download the target OS image and extract it if necessary. postmarketos-ondev expects a foreign target OS image to have two partitions, boot and rootfs .
Once all files are ready, run the following command. The last two lines are optional for integrating the target OS logo into the installer and as boot splash. Leave them out if you just want to test this and don't have the logo in the right format.
$ cd ~/code/ondev-mydistro $ pmbootstrap \ --details-to-stdout \ install \ --ondev \ --no-rootfs \ --cp \ os-image.img:/var/lib/rootfs.img \ mobile.conf:/etc/calamares/modules/mobile.conf \ shellprocess.conf:/etc/calamares/modules/shellprocess.conf \ logo.png:/usr/share/calamares/branding/default-mobile/logo.png \ splash.ppm.gz:/boot/splash.ppm.gz
The resulting image file is here:
$ cd $(pmbootstrap -q config work)/chroot_native/home/pmos/rootfs $ ls pine64-pinephone.img
Running in QEMU
You can get a relatively short test cycle by running everything in QEMU (1-2 minutes to build the new install image, run the whole installation and reboot into the target OS).
For the first install, configure pmbootstrap and build the postmarketOS target rootfs with UI=none.
#!/bin/sh -ex pmbootstrap -q -y zap pmbootstrap -q config device qemu-amd64 pmbootstrap -q config ui none pmbootstrap -q config boot_size 128 pmbootstrap -q config extra_space 0 yes | pmbootstrap --details-to-stdout install --ondev export DISPLAY=:0 pmbootstrap qemu --image-size=8G
For all following installs, use
--no-rootfs to save time.
#!/bin/sh -ex yes | pmbootstrap --details-to-stdout install --ondev --no-rootfs export DISPLAY=:0 pmbootstrap qemu --image-size=8G
Building components from source
This section describes how to build packages for various components from their local git trees.
pmbootstrap install will use these versions instead of the official binary packages. Run
pmbootstrap zap -p to delete all previously built packages.
Packages will get usually get built for the host arch. Add
--arch=aarch64 or similar to each
pmbootstrap build line if necessary.
$ git clone https://gitlab.com/postmarketOS/postmarketos-ondev.git $ pmbootstrap aportgen --fork-alpine postmarketos-ondev $ pmbootstrap build --src=postmarketos-ondev postmarketos-ondev
$ git clone https://github.com/calamares/calamares-extensions $ pmbootstrap aportgen --fork-alpine calamares-extensions $ pmbootstrap build --src=calamares-extensions calamares-extensions
$ git clone https://github.com/calamares/calamares.git $ pmbootstrap aportgen --fork-alpine calamares $ pmbootstrap build --src=calamares calamares
How it works
pmbootstrap install --ondev does the following:
- prepares the device rootfs, and create an image from it as usually (more or less)
- prepares a new installer rootfs
- copies the device rootfs image into the installer rootfs as /var/lib/rootfs.img
- installs postmarketos-ondev, postmarketos-base and the device-package into the installer rootfs
- runs ondev-prepare.sh
- creates an image from the installer rootfs, with reserved space
The installer image has the following partition layout:
- p1: label=pmOS_boot
- p2: (reserved space)
- p3: label=pmOS_install
This installer image can be transmitted to the device via the usual methods (fastboot flash, via SD card, ...). When booting into the installer's initramfs, the usual postmarketOS initramfs code will prefer
pmOS_root (so we don't end up in an invalid state if an installation was aborted). So the
pmOS_install partition will be mounted as / and the boot continues.
- calculates ONDEV_PARTITION_TARGET
- configures tinydm and i3, then starts tinydm (we may use something other than i3 in the future, but this works well even with framebuffer devices)
- the config will start Calamares
- loads settings.conf
- shows the custom mobile module
- this module asks for the FDE password, formats the target partition with cryptsetup and ext4 and mounts it (bypassing some of the usual Calamares logic, as Calamares relies on grub2 and encrypted initramfs)
- "unpackfs" extracts rootfs.img and gives a nice progress bar
- "shellprocess" renames pmOS_install to pmOS_deleteme and reboots (also replaces boot partition in foreign target OS case)
The partition layout looks like this now:
- p1: label=pmOS_boot
- p2: label=pmOS_root
- p3: label=pmOS_deleteme
postmarketOS initramfs does the following as target OS during first boot:
- deletes the pmOS_deleteme partition (postmarketos-ondev#1)
- resizes pmOS_root to use up all available free space (even beyond pmOS_deleteme)
- runs osk-sdl as usually for encrypted installations
- boots into pmOS_root