This is a follow-up to the article Installing Arch Linux on a PineBook Pro (external storage); differently from the previous post, this one is based on more automatic mechanisms, so it will be easier to copy and paste commands once a few variables have been correctly and carefully set. Moreover, in this post, I’ll install KDE instead of GNOME. Finally, we’ll use BTRFS for the main partition, instead of EXT4.
This post will describe my experience installing Arch Linux on a PineBook Pro on external storage (a micro SD card in this example). Thus, the Manjaro default installation on the eMMC will not be touched. You should use a fast card, or the overall experience will be extremely slow.
The post is based on the instructions found at https://wiki.pine64.org/wiki/Pinebook_Pro_Software_Release#Arch_Linux_ARM.
The installation process consists of two steps:
- First, install the official Arch Linux ARM distribution; this will not be enough to have many hardware parts working (e.g., WiFi, battery management, and sound).
- Then, add the repositories with kernels and drivers for the PineBook Pro.
The first part must be performed from an existing Linux installation on the PineBook Pro. I will use the Manjaro installation that comes with the PineBook Pro. The second part will be performed on the installed Arch Linux system on an external drive (a USB stick in this example). Since after the Arch Linux installation, the WiFi is not working, for this part, you need to connect to the wired network, e.g., with an ethernet USB adapter.
Finally, I’ll also show how to install KDE.
First part
This is based on https://wiki.pine64.org/wiki/Installing_Arch_Linux_ARM_On_The_Pinebook_Pro.
I insert my SD card, which is /dev/sda. (Use “lsblk” to detect that.) By the way, typically, an SD card should be detected with a device name of the shape “/dev/mmcblkX”, but in this example, the SD card is inserted in a USB adapter, so its device name has the typical shape “/dev/sdX”.
From now on, I’m using this device. In your case, the device name might be different.
From now on, all the instructions are executed as “root” from a terminal window; thus, I first run:
1 |
sudo su - |
I will do the following steps in a directory of the root’s home:
1 2 3 |
cd mkdir pbp-install cd pbp-install |
We need to download and extract the latest release of Tow-Boot for the Pinebook Pro from https://github.com/Tow-Boot/Tow-Boot/releases. At the time of writing, the latest one is “2021.10-005”:
1 2 3 |
wget https://github.com/Tow-Boot/Tow-Boot/releases/download/release-2021.10-005/pine64-pinebookPro-2021.10-005.tar.xz tar xf pine64-pinebookPro-2021.10-005.tar.xz |
Now we flash Tow-Boot to /dev/sda (replace this with the device you are using).
Remember: this will wipe all the contents of the specified device. Moreover, make sure you specify the correct device, or you might overwrite the eMMC of the computer.
To make things easily reproducible and minimize the chances of specifying the wrong device name (which is extremely dangerous), I will use environment variables:
1 |
export DEVICE_NAME="/dev/sda" |
The process creates the partition table for the device, with the first partition for Tow-Boot. This first partition must not be modified further. As you see in a minute, we skip the first partition when we further partition the disk.
1 |
dd if=pine64-pinebookPro-2021.10-005/shared.disk-image.img of=${DEVICE_NAME} bs=1M oflag=direct,sync |
The output should be something like this:
1 2 3 |
13+1 records in 13+1 records out 13648896 bytes (14 MB, 13 MiB) copied, 0.592278 s, 23.0 MB/s |
Now, we must create the partitions on the USB stick. The process is documented step-by-step here https://wiki.pine64.org/wiki/Installing_Arch_Linux_ARM_On_The_Pinebook_Pro#Creating_the_partitions, and must be followed strictly:
1 |
fdisk ${DEVICE_NAME} |
The instructions must be followed strictly concerning, at least, the very first partition (the boot partition) that will be created, which must NOT touch the one created in the previous step. Then, after creating the boot partition, I’ll do things slightly differently: I will create a SWAP partition (not contemplated in the above instructions; The PineBook Pro has only 4 Gb of RAM, and it is likely to exhaust it, so it’s better to have a SWAP partition to avoid system hangs. Then, I’ll create the root partition.
These are the essential contents of my terminal where I follow the above-mentioned instructions (since I had already used this USB stick for some experiments before writing this blog post, fdisk detects an existing ext4 signature). Remember, though, that I created a SWAP partition that was not described in the above-mentioned instructions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
Welcome to fdisk (util-linux 2.38.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. GPT PMBR size mismatch (26657 != 249737215) will be corrected by write. The backup GPT table is not on the end of the device. This problem will be corrected by write. Command (m for help): p Disk /dev/sda: 119.08 GiB, 127865454592 bytes, 249737216 sectors Disk model: SDDR-B531 Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: E0CA6E57-39B2-4482-9838-21E2785CD93D Device Start End Sectors Size Type /dev/sda1 64 24639 24576 12M unknown Command (m for help): n Partition number (2-128, default 2): First sector (24640-249737182, default 26624): Last sector, +/-sectors or +/-size{K,M,G,T,P} (26624-249737182, default 249735167): +256M Created a new partition 2 of type 'Linux filesystem' and of size 256 MiB. Command (m for help): x Expert command (m for help): A Partition number (1,2, default 2): The LegacyBIOSBootable flag on partition 2 is enabled now. Expert command (m for help): r Command (m for help): n Partition number (3-128, default 3): First sector (550912-249737182, default 550912): Last sector, +/-sectors or +/-size{K,M,G,T,P} (550912-249737182, default 249735167): +8G Created a new partition 3 of type 'Linux filesystem' and of size 8 GiB. Partition #3 contains a ext4 signature. Do you want to remove the signature? [Y]es/[N]o: Y The signature will be removed by a write command. Command (m for help): t Partition number (1-3, default 3): Partition type or alias (type L to list all): 19 Changed type of partition 'Linux filesystem' to 'Linux swap'. Command (m for help): n Partition number (4-128, default 4): First sector (17328128-249737182, default 17328128): Last sector, +/-sectors or +/-size{K,M,G,T,P} (17328128-249737182, default 249735167): Created a new partition 4 of type 'Linux filesystem' and of size 110.8 GiB. Command (m for help): p Disk /dev/sda: 119.08 GiB, 127865454592 bytes, 249737216 sectors Disk model: SDDR-B531 Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: E0CA6E57-39B2-4482-9838-21E2785CD93D Device Start End Sectors Size Type /dev/sda1 64 24639 24576 12M unknown /dev/sda2 26624 550911 524288 256M Linux filesystem /dev/sda3 550912 17328127 16777216 8G Linux swap /dev/sda4 17328128 249735167 232407040 110.8G Linux filesystem Filesystem/RAID signature on partition 3 will be wiped. Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks. |
Now I format the boot, the swap, and the root partitions. I will use EXT4 for the boot partition and BTRFS for the root partition.
Again, to increase reproducibility and avoid possible mistakes, I’m going to define additional environment variables, based on the one I have already created above, to refer to the 3 partitions:
1 2 3 |
export BOOT_PARTITION="${DEVICE_NAME}2" export SWAP_PARTITION="${DEVICE_NAME}3" export ROOT_PARTITION="${DEVICE_NAME}4" |
It’s worthwhile to double-check that all the environment variables refer to the right partitions:
1 2 3 4 5 |
set | grep _PARTITION BOOT_PARTITION=/dev/sda2 ROOT_PARTITION=/dev/sda4 SWAP_PARTITION=/dev/sda3 |
Remember that I’m using the environment variables set above:
1 2 3 |
mkfs.ext4 ${BOOT_PARTITION} mkfs.btrfs -f ${ROOT_PARTITION} mkswap ${SWAP_PARTITION} |
Now we mount the root partition to create the BTRFS subvolumes, following a standard scheme, and we unmount it:
1 2 3 4 5 6 7 8 9 |
mount ${ROOT_PARTITION} /mnt btrfs su cr /mnt/@ btrfs su cr /mnt/@home btrfs su cr /mnt/@cache btrfs su cr /mnt/@log btrfs su cr /mnt/@tmp umount /mnt |
Now we have to mount all the subvolumes to the corresponding directories (the “-m” flag creates the mounting subdirectory if it does not exist); I’m enabling BTRFS compression (by default, the compression level for zstd will be 3):
1 2 3 4 5 |
mount -o subvol=/@,defaults,noatime,compress=zstd ${ROOT_PARTITION} /mnt mount -o subvol=/@home,defaults,noatime,compress=zstd -m ${ROOT_PARTITION} /mnt/home mount -o subvol=/@cache,defaults,noatime,compress=zstd -m ${ROOT_PARTITION} /mnt/var/cache mount -o subvol=/@log,defaults,noatime,compress=zstd -m ${ROOT_PARTITION} /mnt/var/log mount -o subvol=/@tmp,defaults,noatime,compress=zstd -m ${ROOT_PARTITION} /mnt/var/tmp |
Then, we mount the boot partition on “/mnt/boot” (again, by creating that):
1 |
mount -m ${BOOT_PARTITION} /mnt/boot |
Let’s verify that the layout of the destination filesystem is as expected:
1 2 3 4 5 6 7 8 9 10 |
tree /mnt/ /mnt/ ├── boot │ └── lost+found ├── home └── var ├── cache ├── log └── tmp |
Now, we download the tarball for the rootfs of our USB stick installation. The instructions are once again taken from the link mentioned above, and they also include the verification of the contents of the downloaded archive:
1 2 3 4 5 |
wget http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz{,.sig} gpg --keyserver keyserver.ubuntu.com --recv-keys 68B3537F39A313B3E574D06777193F152BDBE6A6 gpg --verify ArchLinuxARM-aarch64-latest.tar.gz.sig |
And we extract the root filesystem onto the mounted root partition of our USB stick:
1 |
bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C /mnt |
This is another operation that takes time.
Now, we must create the “/etc/fstab” on the mounted partition. To do that, we need to know the UUID of the two partitions by using “blkid”. You need to take note of the UUID from the output (which will be completely different according to the used external device):
1 2 3 4 5 |
blkid ${ROOT_PARTITION} ${BOOT_PARTITION} ${SWAP_PARTITION} /dev/sda4: UUID="bda19ab2-c45e-4b3b-9d83-46f060fe19e9" UUID_SUB="5147b0a1-2619-4484-8beb-481e347e97c1" BLOCK_SIZE="4096" TYPE="btrfs" PARTUUID="aac9a8ba-9114-e048-9a0f-963641d2a496" /dev/sda2: UUID="423b47bd-4171-40e7-be47-5fc104653ed8" BLOCK_SIZE="1024" TYPE="ext4" PARTUUID="b5ce3c65-21e8-5448-88f6-9f6d8b3054ad" /dev/sda3: UUID="5a5379be-c554-4007-bec9-a854fbc485e8" TYPE="swap" PARTUUID="79ed45fc-e052-9c4b-bd14-d4d21e6aa2ab" |
Let’s take note of the UUIDs (remember, they will be different in your case) and create the corresponding environment variables:
1 2 3 |
export ROOT_UUID="bda19ab2-c45e-4b3b-9d83-46f060fe19e9" export BOOT_UUID="423b47bd-4171-40e7-be47-5fc104653ed8" export SWAP_UUID="5a5379be-c554-4007-bec9-a854fbc485e8" |
We create the file “/etc/fstab” in “/mnt” according to the BTRFS subvolumes and to the other two partitions. This can be done by running the following command, which relies on the values of the 3 environment variables that we have just created:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
cat << EOF >> /mnt/etc/fstab UUID=${ROOT_UUID} / btrfs rw,noatime,compress=zstd:3,space_cache=v2,subvolid=256,subvol=/@ 0 0 UUID=${ROOT_UUID} /home btrfs rw,noatime,compress=zstd:3,space_cache=v2,subvolid=257,subvol=/@home 0 0 UUID=${ROOT_UUID} /var/cache btrfs rw,noatime,compress=zstd:3,space_cache=v2,subvolid=258,subvol=/@cache 0 0 UUID=${ROOT_UUID} /var/log btrfs rw,noatime,compress=zstd:3,space_cache=v2,subvolid=259,subvol=/@log 0 0 UUID=${ROOT_UUID} /var/tmp btrfs rw,noatime,compress=zstd:3,space_cache=v2,subvolid=260,subvol=/@tmp 0 0 UUID=${BOOT_UUID} /boot ext4 defaults,noatime 0 2 UUID=${SWAP_UUID} none swap defaults 0 0 EOF |
Finally, we need to create the file “/mnt/boot/extlinux/extlinux.conf” (the directory must be created first, with:
1 |
mkdir -p /mnt/boot/extlinux |
Once again, the contents are generated by the following command that relies on the environment variable for the UUID of the root partition:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
cat << EOF >> /mnt/boot/extlinux/extlinux.conf DEFAULT arch MENU TITLE Boot Menu PROMPT 0 TIMEOUT 50 LABEL arch MENU LABEL Arch Linux ARM LINUX /Image INITRD /initramfs-linux.img FDT /dtbs/rockchip/rk3399-pinebook-pro.dtb APPEND root=UUID=${ROOT_UUID} rootflags=subvol=@ rw LABEL arch-fallback MENU LABEL Arch Linux ARM with fallback initramfs LINUX /Image INITRD /initramfs-linux-fallback.img FDT /dtbs/rockchip/rk3399-pinebook-pro.dtb APPEND root=UUID=${ROOT_UUID} rootflags=subvol=@ rw EOF |
Note that we must specify “rootflags=subvol=@” because the “/” of is on the subvolume “@”. Otherwise, the system can boot, but then nothing else will work.
We can now unmount the filesystems
1 2 |
umount /mnt/boot umount -R /mnt |
And we can reboot into the (hopefully) installed Arch Linux on the USB stick to finish a few operations. Remember that we need a wired connection for the next steps.
Upon rebooting, you should see the two entries (if you let the timeout expire, it will automatically boot the first entry):
After we get to the prompt, we can log in with “root” and password “root” (needless to say: change the password immediately).
Let’s connect a network cable (you need a USB adapter for that), and after a few seconds, we should be online. We verify that with “ifconfig”, which should show the assigned IP address for “eth0”.
Since there’s no DE yet, I suggest you keep following the official web pages (and this blog post) by connecting to the PineBook Pro via SSH so that it will be easy to copy and paste commands into the terminal window of another computer. Moreover, when logged into the PineBook Pro directly, you will see lots of logging information directly on the console (I guess this could be prevented by passing specific options to the kernel, but we’ll install a DE later, so I don’t care about that much). The SSH server is already up and running in the PineBook Pro installed system, so once we know the IP address from the output of “ifconfig”, we can connect via SSH. However, root access via SSH is disabled, so we must connect with the other predefined account “alarm” and password “alarm” (again, you might want to change this password right away):
1 |
ssh alarm@<ip address> |
Once we’re logged in since “sudo” is not yet configured, we switch to root:
1 |
su - |
We have to initialize the pacman keyring:
1 2 |
pacman-key --init pacman-key --populate archlinuxarm |
The guide https://wiki.pine64.org/wiki/Installing_Arch_Linux_ARM_On_The_Pinebook_Pro ends at this point.
What follows are my own instructions I usually run when installing Arch.
In particular, I configure time, network time synchronization, and timezone (Italy, in my case):
1 2 3 4 5 |
timedatectl set-timezone Europe/Rome timedatectl set-ntp on hwclock --systohc |
The next step is required for doing gnome-terminal work (and it’s also part of the Arch standard installation instructions):
Edit “/etc/locale.gen” and uncomment “en_US.UTF-8 UTF-8” and other needed locales.
Generate the locales by running:
1 |
locale-gen |
Edit the “/etc/locale.conf” file, and set the LANG variable accordingly, for example, for the UTF-8 local above:
1 |
LANG=en_US.UTF-8 |
We could run a first system upgrade
1 |
pacman -Syu |
I don’t know if that’s strictly required because we’ll add the additional repository for the PineBook Pro in a minute. However, just in case, it might be better to update the system.
Let’s reboot and verify that everything still works.
The kernel at the time of writing is
1 2 |
uname -a Linux alarm 5.19.8-1-aarch64-ARCH #1 SMP PREEMPT Thu Sep 8 18:20:33 MDT 2022 aarch64 GNU/Linux |
NOTE: By the way, I noted that if I want to boot from the USB stick, it’s better to use the right-hand side USB port (which is USB 2) instead of the left-hand side port (USB 3). Otherwise, the system seems to ignore the system on the USB stick and boots directly to the installed Manjaro system.
Second part
As mentioned above, I suggest connecting to the PineBook Pro via SSH. In any case, what follows must be executed as “root” (“su -“).
Let’s now add the repositories with kernels and drivers specific to PineBook Pro.
The project is documented here: https://github.com/SvenKiljan/archlinuxarm-pbp, and these are the contents of the additional repository that we’ll add in a minute https://pacman.kiljan.org/archlinuxarm-pbp/os/aarch64/.
Note that this project also provides a way to install Arch Linux directly with these repositories, with a procedure similar to the one in the first part. I prefer to install official Arch Linux first and then add the additional repositories, though.
The addition of the PineBook Pro repository to an existing Arch Linux installation and the installation of specific kernel and drivers is documented as a FAQ: https://github.com/SvenKiljan/archlinuxarm-pbp/blob/main/FAQ.md#how-do-i-migrate-from-other-arch-linux-arm-releases-for-the-pinebook-pro.
The addition of the PGP key and the repositories to “/etc/pacman.conf” is done by pasting the following commands (remember, as the user “root”):
1 2 3 4 5 6 7 8 9 |
pacman-key --keyserver hkps://keys.openpgp.org/ --recv-keys A1EC3C686EF7A9DD232D1563D4D12D6AA6A92769 pacman-key --lsign-key A1EC3C686EF7A9DD232D1563D4D12D6AA6A92769 cat << 'EOF' >> /etc/pacman.conf [archlinuxarm-pbp] SigLevel = Optional TrustedOnly Server = http://pacman.kiljan.org/$repo/os/$arch EOF |
Let’s now synchronize the repositories
1 |
pacman -Sy |
And let’s install the packages specific to the PineBook Pro (note that we’re going to install the Linux kernel patched by Manjaro for the PineBook Pro):
1 |
pacman -S ap6256-firmware libdrm-pinebookpro linux-manjaro pinebookpro-audio pinebookpro-post-install towboot-pinebookpro-bin |
Of course, we’ll have to answer “y” to the following question:
1 |
:: linux-manjaro and linux-aarch64 are in conflict (linux). Remove linux-aarch64? [y/N] |
Let’s reboot and verify that everything still works (again, by connecting via SSH).
Now, we should be using the new kernel:
1 2 |
uname -a Linux alarm 6.0.10-1-MANJARO-ARM #1 SMP PREEMPT Sat Nov 26 12:11:25 CET 2022 aarch64 GNU/Linux |
Before installing a DE, I prefer creating a user for myself (“bettini”) and configuring it as a “sudoer”. (We must install “sudo” first).
1 2 3 4 5 |
pacman -S sudo useradd -m bettini passwd bettini usermod -aG wheel,sys,rfkill bettini |
Then (by simply running “visudo”), we enable the users of the group “wheel” in “/etc/sudoers”; that is, we uncomment this line:
1 2 |
## Uncomment to allow members of group wheel to execute any command # %wheel ALL=(ALL:ALL) ALL |
Then, I try to re-connect with my user and verify that I can run commands with “sudo” (e.g., “sudo pacman -Syu”).
Install KDE
As usual, I’m still doing these steps via SSH.
I’m going to install KDE with some fonts, pipewire media session, firefox, and the NetworkManager:
1 |
pacman -S --noconfirm firefox noto-fonts noto-fonts-emoji power-profiles-daemon networkmanager pipewire-media-session pipewire-jack xorg plasma kde-graphics yakuake konsole dolphin kate |
It’s about 680 Mb of packages to install, so please be patient.
Now, I enable the primary services (the login manager, the NetworkManager to select a network from KDE, and the profile daemon for switching between power profiles, e.g., “Balanced” and “Powersave”):
1 2 3 |
sudo systemctl enable sddm.service sudo systemctl enable NetworkManager.service sudo systemctl enable power-profiles-daemon.service |
OK, time to reboot.
The graphical SDDM login manager should greet us this time, allowing us to get into KDE and select a WiFi connection.
NOTE: I always hear a strange noise when the login manager or the KDE DE starts. It also happens with the pre-installed Manjaro. It must be the sound card that gets activated…
IMPORTANT NOTE: Upon rebooting, the WiFi does not always work (it looks like the WiFi card is not seen at all); that also happens with Manjaro. The only solution is to shut down the computer (i.e., NOT simply rebooting it) and boot it again.
Here’s the KDE About dialog:
And of course, once installed, let’s run “neofetch”:
That’s all for now!
In a future blog post, I’ll describe my customizations to KDE (installed programs and configurations).
Stay tuned! 🙂