Jump to content

pmbootstrap/Using pmbootstrap

From postmarketOS Wiki

Frequent users may want to set up tab completion at this point, to be able to automatically complete your pmbootstrap commands and arguments with the tab key while writing them.

Initialization

Initialization

Installing postmarketOS

TODO TODO: Merge with Porting to a new device.

Depending on the device, the installation instructions may be quite different. You might need to unlock or flash a bootloader before continuing here, or you may need to use a specific install command. Make sure you read the installation section of your device's wiki page first.

All device ports have in common that they run some form of the pmbootstrap install command at one point. It will build a chroot with the full installation as it will be placed on the device, copy it to an image file or write it directly to an SD card and ask you for the user and encryption password. Below are the most commonly used pmbootstrap install commands.

All examples have --fde added to enable Full Disk Encryption. Omit it if you don't want to encrypt your device or if your device port isn't able to show the FDE prompt yet (see FDE column of the all devices table).

Find all available arguments (such as ones for choosing different filesystems etc.) with pmbootstrap install --help.

pmbootstrap install

SD card

Devices like the PinePhone, Samsung Galaxy S II, Nokia N900, various laptops etc. boot from an SD card, USB stick or other external storage. Find the name with lsblk first and make sure it is the right one as you will overwrite everything on it. Use a path without partition number at the end, such as /dev/mmcblk0.

$ pmbootstrap install --sdcard=/dev/mmcblk... --fde

If your device is able to boot from SD card without flashing anything (such as the PinePhone), you should now be able to insert it into your device and boot it up. You are done with installing postmarketOS, congratulations!

To make Androids like the Samsung Galaxy S II boot from SD card, you will need to flash a boot.img file to the internal storage. Read on at #flash_kernel.

Encrypted Image file

Most Androids, the Librem 5 and other devices need to have an image file generated, that will then be flashed to the device while it is in a special flashing mode. To generate such an image, run:

$ pmbootstrap install --fde

Then read on at #pmbootstrap flasher.

Android recovery zip

A less reliable, but for some devices required method is using the Android recovery zip. The Installation from recovery mode article explains how to generate the zip file and how to flash it.

pmbootstrap flasher

This action wraps various flash programs (e.g. fastboot and heimdall) with a common syntax, and automatically fills out the paths to the files generated earlier during pmbootstrap install. Bring your phone into the flashing mode, typically by holding a special button combination such as Power + Volume Down while booting up. This should be described in your device's wiki page.

If you specify partition names below, note that they are case sensitive. If flashing onto a Samsung device, you can use heimdall print-pit to verify the names.

flash_rootfs

Warning WARNING: Doing this will ERASE ALL DATA on your device. Please backup all your personal data before continuing!

Flash the rootfs to internal storage. You will need to do this, unless you plan to boot the rootfs from elsewhere, such as from SD card. Beware that this will overwrite the existing installation/data on your phone!

$ pmbootstrap flasher flash_rootfs

For Androids, we don't change the partition layout. If the default partition (typically "system") is too small for the generated image, it is possible to flash to another partition. Just be sure to erase any previous installations of postmarketOS in other partitions, because the init script will start with the first one that it encounters. (To delete a previous version either use fastboot format system for fastboot compatible devices, or simply install the known working OS, e.g. Android, on it. And if you really know what you are doing, you might consider using dd). Using multiple partitions with LVM is planned (pmbootstrap#60).

$ pmbootstrap flasher flash_rootfs --partition userdata

flash_kernel

For Androids, you will also need to flash a boot.img (kernel + initramfs). Instruct pmbootstrap to do so with:

$ pmbootstrap flasher flash_kernel

Afterwards you should be able to restart your phone and postmarketOS should boot up. You are done with installing postmarketOS, congratulations!

Inspecting generated files

If you want to conveniently access the files generated by pmbootstrap install, let pmbootstrap create a bunch of symlinks with export.

$ pmbootstrap export
(rootfs_lg-mako) install device-lg-mako
(rootfs_lg-mako) install postmarketos-mkinitfs
(rootfs_lg-mako) mkinitfs lg-mako
Export symlinks to: /tmp/postmarketOS-export
 * boot.img (Fastboot compatible boot.img file, contains initramfs and kernel)
 * initramfs (Initramfs)
 * initramfs-extra (Extra initramfs files in /boot)
 * vmlinuz (Linux kernel)
 * lg-mako.img (Rootfs with partitions for /boot and /)

Run the following to extract the generated initramfs:

$ pmbootstrap initfs extract

Development actions

Building packages

Build any package from pmaports.git, for example main/hello-world. pmbootstrap will automatically pick one of the architectures that the APKBUILD can be built for, preferably the native architecture of the PC running pmbootstrap, or if that's not possible, the device's architecture. You can explicitly specify an architecture with --arch.

pmbootstrap uses cross compilers as described in detail in the cross compiling article.

$ pmbootstrap build hello-world
$ pmbootstrap build --arch=armv7 hello-world

If you edited the sources of an APKBUILD, update its checksums:

$ pmbootstrap checksum hello-world

To find out where your local APKBUILD copies are saved (for instance, in order to modify them), run:

$ pmbootstrap config aports

If you modify anything in there, you will need to update its checksums and then re-build as above.


To build a package from Alpine, it needs to be forked from Alpine's aports.git first:

$ pmbootstrap aportgen --fork-alpine megapixels
Generate aport: megapixels
Checkout aports.git branch: master
*** pmaport generated: /home/user/.local/var/pmbootstrap/cache_git/pmaports/temp/megapixels
NOTE: chroot is still active (use 'pmbootstrap shutdown' as necessary)
DONE!
$ pmbootstrap build megapixels

It is also possible to specify a local source tree for building a package.

$ git clone https://gitlab.postmarketos.org/postmarketOS/megapixels/
$ pmbootstrap build megapixels --src=megapixels

Generate a template for a new package:

$ pmbootstrap newapkbuild "https://gitlab.postmarketos.org/postmarketOS/osk-sdl/-/archive/0.52/osk-sdl-0.52.tar.bz2"

Entering chroots

Enter the armv7 building chroot:

$ pmbootstrap chroot -b armv7

Run a command inside a chroot:

$ pmbootstrap chroot -- echo test

Safely delete all chroots:

$ pmbootstrap zap

Running CI scripts locally

Before a patch with modifications to pmaports (or other postmarketOS projects, such as pmbootstrap itself) gets accepted, it needs to pass the CI scripts. These run automatically when you submit the patch, but of course it makes sense to run it beforehand on your machine locally. That way you can fix up your patches until it passes and you have a shorter test iteration time than you would have with pushing it to the server every time.

Navigate to the git repository that you have modified and run the ci action.

$ pmbootstrap ci
Available CI scripts (15):
* flake8: lint CI related python scripts/tests
* apkbuild-lint: run apkbuild-lint on modified APKBUILDs
* wiki: verify devices are documented in the wiki
* ec: editorconfig-checker: lint for trailing whitespaces etc.
* pytest: lint with various python tests
* commits: check pkgver/pkgrel bumps, amount of changed pkgs etc
* kconfig: check all kernel configs with 'pmbootstrap kconfig check'
* grep: check various bad patterns with grep
* shellcheck: lint all shell scripts
* build-riscv64: build modified packages for this architecture (slow)
* build-x86: build modified packages for this architecture (slow)
* build-armhf: build modified packages for this architecture (slow)
* build-aarch64: build modified packages for this architecture (slow)
* build-x86_64: build modified packages for this architecture (slow)
* build-armv7: build modified packages for this architecture (slow)
Which script? [all]: 
*** (1/15) RUNNING CI SCRIPT: .ci/flake8.sh [pmbootstrap chroot] ***
...

See the pmbootstrap CI article for more information on this feature.

Device porting assistance

Analyze Android boot.img files (also works with recovery OS images like TWRP):

$ pmbootstrap bootimg_analyze ~/Downloads/twrp-3.7.0_9-0-FP2.img 
NOTE: You will be prompted for your sudo/doas password, so we can set up a chroot to extract and analyze your boot.img file
(native) install file unpackbootimg
Put these variables in the deviceinfo file of your device:

deviceinfo_kernel_cmdline="console=ttyHSL0,115200,n8 androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x3b7 ehci-hcd.park=3 androidboot.bootdevice=msm_sdcc.1"
deviceinfo_generate_bootimg="true"
deviceinfo_bootimg_qcdt="true"
deviceinfo_bootimg_mtk_mkimage="false"
deviceinfo_bootimg_dtb_second="false"
deviceinfo_flash_pagesize="2048"
deviceinfo_flash_offset_base="0x00000000"
deviceinfo_flash_offset_kernel="0x00008000"
deviceinfo_flash_offset_ramdisk="0x02000000"
deviceinfo_flash_offset_second="0x00f00000"
deviceinfo_flash_offset_tags="0x01e00000"

NOTE: chroot is still active (use 'pmbootstrap shutdown' as necessary)
DONE!

Check kernel configs:

$ pmbootstrap kconfig check

Edit a kernel config:

$ pmbootstrap kconfig edit --arch=aarch64 linux-postmarketos-allwinner

Repository maintenance

Generate cross-compiler aports based on the latest version from Alpine's aports:

$ cd "$(pmbootstrap config work)"/cache_git/pmaports/cross
$ pmbootstrap aportgen binutils-* gcc-*

Manually rebuild package index:

$ pmbootstrap index

List pmaports that don't have a binary package:

$ pmbootstrap repo_missing --arch=armhf --overview

Increase the pkgrel for each aport where the binary package has outdated dependencies (e.g. after soname bumps):

$ pmbootstrap pkgrel_bump --auto

Logging

pmbootstrap writes all log output, and each shell command it runs to log.txt inside the work dir. Use the following command to follow the log in a second terminal:

$ pmbootstrap log

Use -v on any action to get verbose logging:

$ pmbootstrap -v build hello-world

Parse a single deviceinfo and return it as JSON:

$ pmbootstrap deviceinfo_parse pine64-pinephone

Parse a single APKBUILD and return it as JSON:

$ pmbootstrap apkbuild_parse hello-world

Parse a package from an APKINDEX and return it as JSON:

$ pmbootstrap apkindex_parse $WORK/cache_apk_x86_64/APKINDEX.8b865e19.tar.gz hello-world

Clean up

The zap action is used to clean up files generated while using pmbootstrap:

Remove all chroots:
$ pmbootstrap zap

Remove all chroots and built packages:
$ pmbootstrap zap -p

See all options:
$ pmbootstrap zap --help

Removing and recreating chroots is relatively fast, as the Alpine packages that get installed into the chroots are still cached. Sometimes users ask how to completely remove everything related to pmbootstrap (all caches and the config file), this would be done as follows. You can do this if your pmbootstrap install is completely broken for some reason, and then cleanly re-install it as described in this article.

$ pmbootstrap shutdown
$ export WORK=$(pmbootstrap config work)
# rm -rf "$WORK"
$ rm -f ~/.config/pmbootstrap_v3.cfg
$ rm -f ~/.local/bin/pmbootstrap